UX: improves arrow support in chat emoji picker (#19038)

This commit is contained in:
Joffrey JAFFEUX 2022-11-16 08:52:48 +01:00 committed by GitHub
parent 87b297e76c
commit df7730d938
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 72 additions and 28 deletions

View File

@ -86,7 +86,7 @@ export default class ChatEmojiPicker extends Component {
}
@action
trapKeyUpEvents(event) {
trapKeyDownEvents(event) {
if (event.key === "Escape") {
this.chatEmojiPickerManager.close();
}
@ -94,6 +94,20 @@ export default class ChatEmojiPicker extends Component {
if (event.key === "ArrowUp") {
event.stopPropagation();
}
if (
event.key === "ArrowDown" &&
event.target.classList.contains("dc-filter-input")
) {
event.stopPropagation();
event.preventDefault();
document
.querySelector(
`.chat-emoji-picker__scrollable-content .emoji[tabindex="0"]`
)
?.focus();
}
}
@action
@ -224,29 +238,51 @@ export default class ChatEmojiPicker extends Component {
@action
didNavigateSection(event) {
const sectionEmojis = [
...event.target
.closest(".chat-emoji-picker__section")
.querySelectorAll(".emoji"),
const sectionsEmojis = (section) => [...section.querySelectorAll(".emoji")];
const focusSectionsLastEmoji = (section) => {
const emojis = sectionsEmojis(section);
return emojis[emojis.length - 1].focus();
};
const focusSectionsFirstEmoji = (section) => {
sectionsEmojis(section)[0].focus();
};
const currentSection = event.target.closest(".chat-emoji-picker__section");
const focusFilter = () => {
document.querySelector(".dc-filter-input")?.focus();
};
const allEmojis = () => [
...document.querySelectorAll(
".chat-emoji-picker__scrollable-content .emoji"
),
];
if (event.key === "ArrowRight") {
event.preventDefault();
const nextEmoji = event.target.nextElementSibling;
if (event.target === sectionEmojis[sectionEmojis.length - 1]) {
sectionEmojis[0].focus();
if (nextEmoji) {
nextEmoji.focus();
} else {
event.target.nextElementSibling?.focus();
const nextSection = currentSection.nextElementSibling;
if (nextSection) {
focusSectionsFirstEmoji(nextSection);
}
}
}
if (event.key === "ArrowLeft") {
event.preventDefault();
const prevEmoji = event.target.previousElementSibling;
if (event.target === sectionEmojis[0]) {
sectionEmojis[sectionEmojis.length - 1].focus();
if (prevEmoji) {
prevEmoji.focus();
} else {
event.target.previousElementSibling?.focus();
const prevSection = currentSection.previousElementSibling;
if (prevSection) {
focusSectionsLastEmoji(prevSection);
} else {
focusFilter();
}
}
}
@ -254,21 +290,36 @@ export default class ChatEmojiPicker extends Component {
event.preventDefault();
event.stopPropagation();
sectionEmojis
const nextEmoji = allEmojis()
.filter((c) => c.offsetTop > event.target.offsetTop)
.find((c) => c.offsetLeft === event.target.offsetLeft)
?.focus();
.findBy("offsetLeft", event.target.offsetLeft);
if (nextEmoji) {
nextEmoji.focus();
} else {
// for perf reason all emojis might not be loaded at this point
// but the first one will always be
const nextSection = currentSection.nextElementSibling;
if (nextSection) {
focusSectionsFirstEmoji(nextSection);
}
}
}
if (event.key === "ArrowUp") {
event.preventDefault();
event.stopPropagation();
sectionEmojis
const prevEmoji = allEmojis()
.reverse()
.filter((c) => c.offsetTop < event.target.offsetTop)
.find((c) => c.offsetLeft === event.target.offsetLeft)
?.focus();
.findBy("offsetLeft", event.target.offsetLeft);
if (prevEmoji) {
prevEmoji.focus();
} else {
focusFilter();
}
}
}
@ -278,13 +329,9 @@ export default class ChatEmojiPicker extends Component {
return;
}
if (
event.type === "click" ||
(event.type === "keyup" && event.key === "Enter")
) {
if (event.type === "click" || event.key === "Enter") {
event.preventDefault();
event.stopPropagation();
const originalTarget = event.target;
let emoji = event.target.dataset.emoji;
const tonable = event.target.dataset.tonable;
const diversity = this.chatEmojiReactionStore.diversity;
@ -293,10 +340,7 @@ export default class ChatEmojiPicker extends Component {
}
this.chatEmojiPickerManager.didSelectEmoji(emoji);
schedule("afterRender", () => {
originalTarget.focus();
});
this.appEvents.trigger("chat:focus-composer");
}
}

View File

@ -8,7 +8,7 @@
}}
{{did-insert this.addClickOutsideEventListener}}
{{will-destroy this.removeClickOutsideEventListener}}
{{on "keydown" this.trapKeyUpEvents}}
{{on "keydown" this.trapKeyDownEvents}}
>
<div class="chat-emoji-picker__filter-container">
<DcFilterInput
@ -109,7 +109,7 @@
<div
class="chat-emoji-picker__sections"
{{on "click" this.didSelectEmoji}}
{{on "keyup" this.didSelectEmoji}}
{{on "keydown" this.didSelectEmoji}}
role="button"
>
{{#if (gte this.filteredEmojis.length 0)}}