From 8278798ac08649f7f2c57b8ba09b75af21791e13 Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Fri, 2 Jul 2021 21:06:58 +0530 Subject: [PATCH 1/7] fix: picker an arrow navigation --- src/pages/home/report/EmojiPickerMenu/index.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/pages/home/report/EmojiPickerMenu/index.js b/src/pages/home/report/EmojiPickerMenu/index.js index d7d19762a1b6..05c8eb4f1439 100755 --- a/src/pages/home/report/EmojiPickerMenu/index.js +++ b/src/pages/home/report/EmojiPickerMenu/index.js @@ -97,6 +97,14 @@ class EmojiPickerMenu extends Component { if (document) { this.keyDownHandler = (keyBoardEvent) => { if (keyBoardEvent.key.startsWith('Arrow')) { + // Arrow Down enable arrow navigation + if (this.searchInput.isFocused()) { + if (keyBoardEvent.key !== 'ArrowDown') { + return; + } + this.searchInput.blur(); + } + // Depending on the position of the highlighted emoji after moving and rendering, // toggle which arrow keys can affect the cursor position in the search input. this.toggleArrowKeysOnSearchInput(keyBoardEvent); @@ -110,7 +118,9 @@ class EmojiPickerMenu extends Component { this.props.onEmojiSelected(this.state.filteredEmojis[this.state.highlightedIndex].code); } }; - document.addEventListener('keydown', this.keyDownHandler); + + // Keyboard events are not bubbling in RN-Web + document.addEventListener('keydown', this.keyDownHandler, true); // Re-enable pointer events and hovering over EmojiPickerItems when the mouse moves this.mouseMoveHandler = () => { From c73b130df5df8f356b0b42d30549760a0461944f Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Sat, 3 Jul 2021 02:28:10 +0530 Subject: [PATCH 2/7] removed controlled arrow keys while searching and --- .../home/report/EmojiPickerMenu/index.js | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/src/pages/home/report/EmojiPickerMenu/index.js b/src/pages/home/report/EmojiPickerMenu/index.js index 05c8eb4f1439..f9f0a8fd67e6 100755 --- a/src/pages/home/report/EmojiPickerMenu/index.js +++ b/src/pages/home/report/EmojiPickerMenu/index.js @@ -97,18 +97,6 @@ class EmojiPickerMenu extends Component { if (document) { this.keyDownHandler = (keyBoardEvent) => { if (keyBoardEvent.key.startsWith('Arrow')) { - // Arrow Down enable arrow navigation - if (this.searchInput.isFocused()) { - if (keyBoardEvent.key !== 'ArrowDown') { - return; - } - this.searchInput.blur(); - } - - // Depending on the position of the highlighted emoji after moving and rendering, - // toggle which arrow keys can affect the cursor position in the search input. - this.toggleArrowKeysOnSearchInput(keyBoardEvent); - // Move the highlight when arrow keys are pressed this.highlightAdjacentEmoji(keyBoardEvent.key); } @@ -262,27 +250,6 @@ class EmojiPickerMenu extends Component { this.setState({filteredEmojis: newFilteredEmojiList, headerIndices: [], highlightedIndex: 0}); } - /** - * Toggles which arrow keys can affect the cursor in the search input, - * depending on whether the arrow keys will affect the index of the highlighted emoji. - * - * @param {KeyboardEvent} arrowKeyBoardEvent - */ - toggleArrowKeysOnSearchInput(arrowKeyBoardEvent) { - let keysToIgnore = ['ArrowDown', 'ArrowRight', 'ArrowLeft', 'ArrowUp']; - if (this.state.highlightedIndex === 0 && this.state.filteredEmojis.length) { - keysToIgnore = ['ArrowDown', 'ArrowRight']; - } else if (this.state.highlightedIndex === this.state.filteredEmojis.length - 1) { - keysToIgnore = ['ArrowLeft', 'ArrowUp']; - } - - // Moving the cursor is the default behavior for arrow key presses while an input is focused, - // so prevent it - if (keysToIgnore.includes(arrowKeyBoardEvent.key)) { - arrowKeyBoardEvent.preventDefault(); - } - } - /** * Given an emoji item object, render a component based on its type. * Items with the code "SPACER" return nothing and are used to fill rows up to 8 From 7ee9b36a6f586f6b1b713c6a997f855a684a3708 Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Sat, 3 Jul 2021 02:29:03 +0530 Subject: [PATCH 3/7] arrow down enable navigation when searching & move focus back to input when reached start --- .../home/report/EmojiPickerMenu/index.js | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/pages/home/report/EmojiPickerMenu/index.js b/src/pages/home/report/EmojiPickerMenu/index.js index f9f0a8fd67e6..bce21ad766e9 100755 --- a/src/pages/home/report/EmojiPickerMenu/index.js +++ b/src/pages/home/report/EmojiPickerMenu/index.js @@ -137,6 +137,14 @@ class EmojiPickerMenu extends Component { highlightAdjacentEmoji(arrowKey) { const firstNonHeaderIndex = this.state.filteredEmojis.length === this.emojis.length ? this.numColumns : 0; + // Arrow Down enable arrow navigation when search is focused + if (this.searchInput.isFocused() && this.state.filteredEmojis.length) { + if (arrowKey !== 'ArrowDown') { + return; + } + this.searchInput.blur(); + } + // If nothing is highlighted and an arrow key is pressed // select the first emoji if (this.state.highlightedIndex === -1) { @@ -146,8 +154,9 @@ class EmojiPickerMenu extends Component { } let newIndex = this.state.highlightedIndex; - const move = (steps, boundsCheck) => { + const move = (steps, boundsCheck, onBoundReached = () => {}) => { if (boundsCheck()) { + onBoundReached(); return; } @@ -172,7 +181,15 @@ class EmojiPickerMenu extends Component { move(1, () => this.state.highlightedIndex + 1 > this.state.filteredEmojis.length - 1); break; case 'ArrowUp': - move(-this.numColumns, () => this.state.highlightedIndex - this.numColumns < firstNonHeaderIndex); + move( + -this.numColumns, + () => this.state.highlightedIndex - this.numColumns < firstNonHeaderIndex, + () => { + // Reaching start of the list, arrow up set the focus to searchInput. + this.searchInput.focus(); + newIndex = -1; + }, + ); break; default: break; From add0e4e9f1dec8b72700f339c05204fd880a182f Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Sun, 4 Jul 2021 06:42:10 +0530 Subject: [PATCH 4/7] fix Arrow navigation --- src/pages/home/report/EmojiPickerMenu/index.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/pages/home/report/EmojiPickerMenu/index.js b/src/pages/home/report/EmojiPickerMenu/index.js index bce21ad766e9..dbc14117e406 100755 --- a/src/pages/home/report/EmojiPickerMenu/index.js +++ b/src/pages/home/report/EmojiPickerMenu/index.js @@ -61,7 +61,6 @@ class EmojiPickerMenu extends Component { this.filterEmojis = _.debounce(this.filterEmojis.bind(this), 300); this.highlightAdjacentEmoji = this.highlightAdjacentEmoji.bind(this); this.scrollToHighlightedIndex = this.scrollToHighlightedIndex.bind(this); - this.toggleArrowKeysOnSearchInput = this.toggleArrowKeysOnSearchInput.bind(this); this.setupEventHandlers = this.setupEventHandlers.bind(this); this.cleanupEventHandlers = this.cleanupEventHandlers.bind(this); this.renderItem = this.renderItem.bind(this); @@ -125,7 +124,7 @@ class EmojiPickerMenu extends Component { */ cleanupEventHandlers() { if (document) { - document.removeEventListener('keydown', this.keyDownHandler); + document.removeEventListener('keydown', this.keyDownHandler, true); document.removeEventListener('mousemove', this.mouseMoveHandler); } } @@ -138,11 +137,17 @@ class EmojiPickerMenu extends Component { const firstNonHeaderIndex = this.state.filteredEmojis.length === this.emojis.length ? this.numColumns : 0; // Arrow Down enable arrow navigation when search is focused - if (this.searchInput.isFocused() && this.state.filteredEmojis.length) { + if (this.searchInput && this.searchInput.isFocused() && this.state.filteredEmojis.length) { if (arrowKey !== 'ArrowDown') { return; } this.searchInput.blur(); + + // 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 + if (this.state.highlightedIndex !== -1) { + return; + } } // If nothing is highlighted and an arrow key is pressed @@ -185,6 +190,10 @@ class EmojiPickerMenu extends Component { -this.numColumns, () => this.state.highlightedIndex - this.numColumns < firstNonHeaderIndex, () => { + if (!this.searchInput) { + return; + } + // Reaching start of the list, arrow up set the focus to searchInput. this.searchInput.focus(); newIndex = -1; From 474930bff87e3a223f22f2a7e719dca1cfb7df82 Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Thu, 8 Jul 2021 03:41:15 +0530 Subject: [PATCH 5/7] adjust arrow navigation --- src/pages/home/report/EmojiPickerMenu/index.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/pages/home/report/EmojiPickerMenu/index.js b/src/pages/home/report/EmojiPickerMenu/index.js index dbc14117e406..111da362738c 100755 --- a/src/pages/home/report/EmojiPickerMenu/index.js +++ b/src/pages/home/report/EmojiPickerMenu/index.js @@ -98,11 +98,23 @@ class EmojiPickerMenu extends Component { if (keyBoardEvent.key.startsWith('Arrow')) { // Move the highlight when arrow keys are pressed this.highlightAdjacentEmoji(keyBoardEvent.key); + return; } // Select the currently highlighted emoji if enter is pressed if (keyBoardEvent.key === 'Enter' && this.state.highlightedIndex !== -1) { this.props.onEmojiSelected(this.state.filteredEmojis[this.state.highlightedIndex].code); + return; + } + + // We allow typing in the search box if any key is pressed apart from Arrow keys. + if (this.searchInput && !this.searchInput.isFocused()) { + this.setState({selectTextOnFocus: false}); + this.searchInput.value = ''; + this.searchInput.focus(); + + // Re-enable selection on the searchInput + this.setState({selectTextOnFocus: true}); } }; @@ -326,6 +338,7 @@ class EmojiPickerMenu extends Component { defaultValue="" ref={el => this.searchInput = el} autoFocus + selectTextOnFocus={this.state.selectTextOnFocus} /> )} From 1e7ad23de27841b8410a01c64b5ea99ebae62d8c Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Thu, 8 Jul 2021 03:43:26 +0530 Subject: [PATCH 6/7] comment --- src/pages/home/report/EmojiPickerMenu/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/home/report/EmojiPickerMenu/index.js b/src/pages/home/report/EmojiPickerMenu/index.js index 111da362738c..c4eb76cad332 100755 --- a/src/pages/home/report/EmojiPickerMenu/index.js +++ b/src/pages/home/report/EmojiPickerMenu/index.js @@ -118,7 +118,8 @@ class EmojiPickerMenu extends Component { } }; - // Keyboard events are not bubbling in RN-Web + // Keyboard events are not bubbling on TextInput in RN-Web, Bubbling was needed for this event to trigger + // event is attached to document. To fix this attach event in Capture phase. document.addEventListener('keydown', this.keyDownHandler, true); // Re-enable pointer events and hovering over EmojiPickerItems when the mouse moves From fbb073e84e47623fd4ad2824e2f1ec86bcba85b1 Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Thu, 8 Jul 2021 15:32:47 -0700 Subject: [PATCH 7/7] Update src/pages/home/report/EmojiPickerMenu/index.js Co-authored-by: Rory Abraham <47436092+roryabraham@users.noreply.github.com> --- src/pages/home/report/EmojiPickerMenu/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/EmojiPickerMenu/index.js b/src/pages/home/report/EmojiPickerMenu/index.js index c4eb76cad332..7ec87dd556a4 100755 --- a/src/pages/home/report/EmojiPickerMenu/index.js +++ b/src/pages/home/report/EmojiPickerMenu/index.js @@ -119,7 +119,7 @@ class EmojiPickerMenu extends Component { }; // Keyboard events are not bubbling on TextInput in RN-Web, Bubbling was needed for this event to trigger - // event is attached to document. To fix this attach event in Capture phase. + // event handler attached to document root. To fix this, trigger event handler in Capture phase. document.addEventListener('keydown', this.keyDownHandler, true); // Re-enable pointer events and hovering over EmojiPickerItems when the mouse moves