diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index aea3b0f5b984..ceae3b4578e2 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -107,6 +107,7 @@ function EmojiPickerMenu(props) { const [selection, setSelection] = useState({start: 0, end: 0}); const [isFocused, setIsFocused] = useState(false); const [isUsingKeyboardMovement, setIsUsingKeyboardMovement] = useState(false); + const [highlightFirstEmoji, setHighlightFirstEmoji] = useState(false); useEffect(() => { const emojisAndHeaderRowIndices = getEmojisAndHeaderRowIndices(); @@ -174,6 +175,7 @@ function EmojiPickerMenu(props) { setHeaderIndices(headerRowIndices.current); setHighlightedIndex(-1); updateFirstNonHeaderIndex(emojis.current); + setHighlightFirstEmoji(false); return; } const newFilteredEmojiList = EmojiUtils.suggestEmojis(`:${normalizedSearchTerm}`, preferredLocale, emojis.current.length); @@ -183,6 +185,7 @@ function EmojiPickerMenu(props) { setHeaderIndices([]); setHighlightedIndex(0); updateFirstNonHeaderIndex(newFilteredEmojiList); + setHighlightFirstEmoji(true); }, throttleTime); /** @@ -209,6 +212,7 @@ function EmojiPickerMenu(props) { searchInputRef.current.blur(); setArePointerEventsDisabled(true); setIsUsingKeyboardMovement(true); + setHighlightFirstEmoji(false); // We only want to hightlight the Emoji if none was highlighted already // If we already have a highlighted Emoji, lets just skip the first navigation @@ -434,11 +438,13 @@ function EmojiPickerMenu(props) { const emojiCode = types && types[preferredSkinTone] ? types[preferredSkinTone] : code; const isEmojiFocused = index === highlightedIndex && isUsingKeyboardMovement; + const shouldEmojiBeHighlighted = index === highlightedIndex && highlightFirstEmoji; return ( onEmojiSelected(emoji, item)} onHoverIn={() => { + setHighlightFirstEmoji(false); if (!isUsingKeyboardMovement) { return; } @@ -452,10 +458,11 @@ function EmojiPickerMenu(props) { setHighlightedIndex((prevState) => (prevState === index ? -1 : prevState)) } isFocused={isEmojiFocused} + isHighlighted={shouldEmojiBeHighlighted} /> ); }, - [isUsingKeyboardMovement, highlightedIndex, onEmojiSelected, preferredSkinTone, translate], + [isUsingKeyboardMovement, highlightedIndex, onEmojiSelected, preferredSkinTone, translate, highlightFirstEmoji], ); const isFiltered = emojis.current.length !== filteredEmojis.length; diff --git a/src/components/EmojiPicker/EmojiPickerMenuItem/index.js b/src/components/EmojiPicker/EmojiPickerMenuItem/index.js index c5ca5463aec4..1b3e457f7525 100644 --- a/src/components/EmojiPicker/EmojiPickerMenuItem/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenuItem/index.js @@ -29,6 +29,9 @@ const propTypes = { /** Whether this menu item is currently focused or not */ isFocused: PropTypes.bool, + + /** Whether the menu item should be highlighted or not */ + isHighlighted: PropTypes.bool, }; class EmojiPickerMenuItem extends PureComponent { @@ -56,6 +59,7 @@ class EmojiPickerMenuItem extends PureComponent { if (!this.props.isFocused) { return; } + this.focusAndScroll(); } @@ -91,7 +95,7 @@ class EmojiPickerMenuItem extends PureComponent { ref={(ref) => (this.ref = ref)} style={({pressed}) => [ this.props.isFocused ? styles.emojiItemKeyboardHighlighted : {}, - this.state.isHovered ? styles.emojiItemHighlighted : {}, + this.state.isHovered || this.props.isHighlighted ? styles.emojiItemHighlighted : {}, Browser.isMobile() && StyleUtils.getButtonBackgroundColorStyle(getButtonState(false, pressed)), styles.emojiItem, ]} @@ -107,6 +111,7 @@ class EmojiPickerMenuItem extends PureComponent { EmojiPickerMenuItem.propTypes = propTypes; EmojiPickerMenuItem.defaultProps = { isFocused: false, + isHighlighted: false, onHoverIn: () => {}, onHoverOut: () => {}, onFocus: () => {}, @@ -115,4 +120,7 @@ EmojiPickerMenuItem.defaultProps = { // Significantly speeds up re-renders of the EmojiPickerMenu's FlatList // by only re-rendering at most two EmojiPickerMenuItems that are highlighted/un-highlighted per user action. -export default React.memo(EmojiPickerMenuItem, (prevProps, nextProps) => prevProps.isFocused === nextProps.isFocused && prevProps.emoji === nextProps.emoji); +export default React.memo( + EmojiPickerMenuItem, + (prevProps, nextProps) => prevProps.isFocused === nextProps.isFocused && prevProps.isHighlighted === nextProps.isHighlighted && prevProps.emoji === nextProps.emoji, +);