From 95ab0b483704ebae577d61afbfa29017a91a2fef Mon Sep 17 00:00:00 2001 From: Tom Hutman Date: Tue, 16 Mar 2021 15:23:03 +0100 Subject: [PATCH 1/3] ensure dropdownScroll callback is called on up/down key press --- src/components/AutoCompleteTextarea/List.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/components/AutoCompleteTextarea/List.js b/src/components/AutoCompleteTextarea/List.js index 5c871d9ae4..a115553c11 100644 --- a/src/components/AutoCompleteTextarea/List.js +++ b/src/components/AutoCompleteTextarea/List.js @@ -24,7 +24,7 @@ const List = (props) => { const [selectedItem, setSelectedItem] = useState(undefined); - const itemsRef = {}; + const itemsRef = []; const isSelected = (item) => selectedItem === values.indexOf(item); @@ -53,9 +53,8 @@ const List = (props) => { modifyText(values[selectedItem]); }; - const selectItem = (item, keyboard = false) => { + const selectItem = (item) => { setSelectedItem(values.indexOf(item)); - if (keyboard) dropdownScroll(itemsRef[getId(item)]); }; const handleKeyDown = useCallback( @@ -63,14 +62,20 @@ const List = (props) => { if (event.which === KEY_CODES.UP) { setSelectedItem((prevSelected) => { if (prevSelected === undefined) return 0; - return prevSelected === 0 ? values.length - 1 : prevSelected - 1; + const newID = + prevSelected === 0 ? values.length - 1 : prevSelected - 1; + dropdownScroll(itemsRef[newID]); + return newID; }); } if (event.which === KEY_CODES.DOWN) { setSelectedItem((prevSelected) => { if (prevSelected === undefined) return 0; - return prevSelected === values.length - 1 ? 0 : prevSelected + 1; + const newID = + prevSelected === values.length - 1 ? 0 : prevSelected + 1; + dropdownScroll(itemsRef[newID]); + return newID; }); } @@ -123,7 +128,7 @@ const List = (props) => { __html: renderHeader(propValue), }} /> - {values.map((item) => ( + {values.map((item, i) => ( { onClickHandler={handleClick} onSelectHandler={selectItem} ref={(ref) => { - itemsRef[getId(item)] = ref; + itemsRef[i] = ref; }} selected={isSelected(item)} style={itemStyle} From 546c8bb9385c4cd8c5d4b0dd018e7dd489c462e4 Mon Sep 17 00:00:00 2001 From: Tom Hutman Date: Tue, 16 Mar 2021 16:58:33 +0100 Subject: [PATCH 2/3] pull out SuggestionListContainer component from render method, put in separate class method to prevent re-renders of the same component --- .../AutoCompleteTextarea/Textarea.js | 83 +++++++++---------- 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/src/components/AutoCompleteTextarea/Textarea.js b/src/components/AutoCompleteTextarea/Textarea.js index 7affaeb89f..9cc7db6292 100644 --- a/src/components/AutoCompleteTextarea/Textarea.js +++ b/src/components/AutoCompleteTextarea/Textarea.js @@ -619,62 +619,61 @@ class ReactTextareaAutocomplete extends React.Component { scrollToItem(this.dropdownRef, item); }; - render() { + renderSuggestionListContainer() { const { - className, - containerClassName, - containerStyle, disableMentions, dropdownClassName, dropdownStyle, itemClassName, itemStyle, listClassName, - style, SuggestionList = DefaultSuggestionList, } = this.props; - - let { maxRows } = this.props; - const { component, currentTrigger, dataLoading, value } = this.state; const selectedItem = this._getItemOnSelect(); const suggestionData = this._getSuggestions(); const textToReplace = this._getTextToReplace(); - const SuggestionListContainer = () => { - if ( - (dataLoading || suggestionData) && - currentTrigger && - !(disableMentions && currentTrigger === '@') - ) { - return ( -
{ - this.dropdownRef = ref; - }} - style={dropdownStyle} - > - {component && suggestionData && textToReplace && ( - - )} -
- ); - } - return null; - }; + if ( + (dataLoading || suggestionData) && + currentTrigger && + !(disableMentions && currentTrigger === '@') + ) { + return ( +
{ + this.dropdownRef = ref; + }} + style={dropdownStyle} + > + {component && suggestionData && textToReplace && ( + + )} +
+ ); + } + return null; + } + + render() { + const { className, containerClassName, containerStyle, style } = this.props; + + let { maxRows } = this.props; + + const { dataLoading, value } = this.state; if (!this.props.grow) maxRows = 1; @@ -685,7 +684,7 @@ class ReactTextareaAutocomplete extends React.Component { }`} style={containerStyle} > - + {this.renderSuggestionListContainer()}