Add arrow key controls to emoji and reaction pickers (#10637)

* Add arrow key controls to emoji and reaction pickers

* Iterate types

* Switch to using aria-activedescendant

* Add tests

* Fix tests

* Iterate

* Update test

* Tweak header keyboard navigation behaviour

* Also handle scrolling on left/right arrow keys

* Iterate
This commit is contained in:
Michael Telatynski 2023-04-20 15:56:21 +01:00 committed by GitHub
parent 0d9fa0515d
commit 2da52372d4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 277 additions and 74 deletions

View file

@ -21,6 +21,7 @@ import { CATEGORY_HEADER_HEIGHT, EMOJI_HEIGHT, EMOJIS_PER_ROW } from "./EmojiPic
import LazyRenderList from "../elements/LazyRenderList";
import { DATA_BY_CATEGORY, IEmoji } from "../../../emoji";
import Emoji from "./Emoji";
import { ButtonEvent } from "../elements/AccessibleButton";
const OVERFLOW_ROWS = 3;
@ -42,18 +43,31 @@ interface IProps {
heightBefore: number;
viewportHeight: number;
scrollTop: number;
onClick(emoji: IEmoji): void;
onClick(ev: ButtonEvent, emoji: IEmoji): void;
onMouseEnter(emoji: IEmoji): void;
onMouseLeave(emoji: IEmoji): void;
isEmojiDisabled?: (unicode: string) => boolean;
}
function hexEncode(str: string): string {
let hex: string;
let i: number;
let result = "";
for (i = 0; i < str.length; i++) {
hex = str.charCodeAt(i).toString(16);
result += ("000" + hex).slice(-4);
}
return result;
}
class Category extends React.PureComponent<IProps> {
private renderEmojiRow = (rowIndex: number): JSX.Element => {
const { onClick, onMouseEnter, onMouseLeave, selectedEmojis, emojis } = this.props;
const emojisForRow = emojis.slice(rowIndex * 8, (rowIndex + 1) * 8);
return (
<div key={rowIndex}>
<div key={rowIndex} role="row">
{emojisForRow.map((emoji) => (
<Emoji
key={emoji.hexcode}
@ -63,6 +77,8 @@ class Category extends React.PureComponent<IProps> {
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
disabled={this.props.isEmojiDisabled?.(emoji.unicode)}
id={`mx_EmojiPicker_item_${this.props.id}_${hexEncode(emoji.unicode)}`}
role="gridcell"
/>
))}
</div>
@ -101,7 +117,6 @@ class Category extends React.PureComponent<IProps> {
>
<h2 className="mx_EmojiPicker_category_label">{name}</h2>
<LazyRenderList
element="ul"
className="mx_EmojiPicker_list"
itemHeight={EMOJI_HEIGHT}
items={rows}
@ -110,6 +125,7 @@ class Category extends React.PureComponent<IProps> {
overflowItems={OVERFLOW_ROWS}
overflowMargin={0}
renderItem={this.renderEmojiRow}
role="grid"
/>
</section>
);