From 8b879b2b3274efa0574fb49c7142b68df1f0c0aa Mon Sep 17 00:00:00 2001 From: Daniel Macak Date: Fri, 28 Jun 2024 13:59:16 +0200 Subject: [PATCH] fix: pick up SR's emoji selection correctly Emojis can be selected by screen reader which happens outside of the emoji-mart's current selection mechanism. It currently relies on either mouse enter or kbd arrow navigation, but neither is necessarily triggered by screen readers. However, SRs can still focus the buttons just fine so I use it as a signal to pick up the selection there and set the current position. Relates to PS-20252. --- .../src/components/Picker/Picker.tsx | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/emoji-mart/src/components/Picker/Picker.tsx b/packages/emoji-mart/src/components/Picker/Picker.tsx index c80907f3..04f00b45 100644 --- a/packages/emoji-mart/src/components/Picker/Picker.tsx +++ b/packages/emoji-mart/src/components/Picker/Picker.tsx @@ -549,7 +549,15 @@ export default class Picker extends Component { this.setState({ pos, keyboard: true }, () => { this.scrollTo({ row: pos[0] }) - this.refs.scroll.current.querySelector('button[tabindex="0"]').focus() + const tabbableButton = this.refs.scroll.current.querySelector( + 'button[tabindex="0"]', + ) + + if (!tabbableButton) { + return console.warn('No tabbable button found', pos) + } + + tabbableButton.focus() }) } @@ -770,6 +778,19 @@ export default class Picker extends Component { ? 0 : -1 + const onFocus = () => { + // Emojis can be selected by screen reader which happens outside of the + // emoji-mart's current selection mechanism. It currently relies on + // either mouse enter or kbd arrow navigation, but neither is necessarily + // triggered by screen readers. However, SRs can still focus the buttons + // just fine so I use it as a signal to pick up the selection there and + // set the current position. + if (deepEqual(this.state.pos, pos)) { + return + } + this.setState({ pos }) + } + return (