DEV: Refactor autocomplete scrolling element detection (#19706)

Rather than hardcoding `.hashtag-autocomplete__fadeout` as the
div element to scroll in autocomplete, instead pass it in as
an option via `scrollElementSelector`, then we don't have hashtag
template specific things in the autocomplete lib.
This commit is contained in:
Martin Brennan 2023-01-04 14:11:52 +10:00 committed by GitHub
parent 81c3c746d3
commit 42cf32169d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 11 deletions

View File

@ -94,7 +94,7 @@ export default function (options) {
let completeEnd = null; let completeEnd = null;
let me = this; let me = this;
let div = null; let div = null;
let fadeoutDiv = null; let scrollElement = null;
let prevTerm = null; let prevTerm = null;
// By default, when the autocomplete popup is rendered it has the // By default, when the autocomplete popup is rendered it has the
@ -119,28 +119,29 @@ export default function (options) {
} }
function scrollAutocomplete() { function scrollAutocomplete() {
if (!fadeoutDiv && !div) { if (!scrollElement && !div) {
return; return;
} }
const scrollingDivElement = fadeoutDiv?.length > 0 ? fadeoutDiv[0] : div[0]; const scrollingElement =
scrollElement?.length > 0 ? scrollElement[0] : div[0];
const selectedElement = getSelectedOptionElement(); const selectedElement = getSelectedOptionElement();
const selectedElementTop = selectedElement.offsetTop; const selectedElementTop = selectedElement.offsetTop;
const selectedElementBottom = const selectedElementBottom =
selectedElementTop + selectedElement.clientHeight; selectedElementTop + selectedElement.clientHeight;
// the top of the item is above the top of the fadeoutDiv, so scroll UP // the top of the item is above the top of the scrollElement, so scroll UP
if (selectedElementTop <= scrollingDivElement.scrollTop) { if (selectedElementTop <= scrollingElement.scrollTop) {
scrollingDivElement.scrollTo(0, selectedElementTop); scrollingElement.scrollTo(0, selectedElementTop);
// the bottom of the item is below the bottom of the div, so scroll DOWN // the bottom of the item is below the bottom of the div, so scroll DOWN
} else if ( } else if (
selectedElementBottom >= selectedElementBottom >=
scrollingDivElement.scrollTop + scrollingDivElement.clientHeight scrollingElement.scrollTop + scrollingElement.clientHeight
) { ) {
scrollingDivElement.scrollTo( scrollingElement.scrollTo(
0, 0,
scrollingDivElement.scrollTop + selectedElement.clientHeight scrollingElement.scrollTop + selectedElement.clientHeight
); );
} }
} }
@ -152,7 +153,7 @@ export default function (options) {
div.hide().remove(); div.hide().remove();
} }
div = null; div = null;
fadeoutDiv = null; scrollElement = null;
completeStart = null; completeStart = null;
autocompleteOptions = null; autocompleteOptions = null;
prevTerm = null; prevTerm = null;
@ -377,7 +378,9 @@ export default function (options) {
me.parent().append(div); me.parent().append(div);
} }
fadeoutDiv = div.find(".hashtag-autocomplete__fadeout"); if (options.scrollElementSelector) {
scrollElement = div.find(options.scrollElementSelector);
}
if (isInput || options.treatAsTextarea) { if (isInput || options.treatAsTextarea) {
_autoCompletePopper && _autoCompletePopper.destroy(); _autoCompletePopper && _autoCompletePopper.destroy();

View File

@ -123,6 +123,7 @@ function _setupExperimental(
key: "#", key: "#",
afterComplete: autocompleteOptions.afterComplete, afterComplete: autocompleteOptions.afterComplete,
treatAsTextarea: autocompleteOptions.treatAsTextarea, treatAsTextarea: autocompleteOptions.treatAsTextarea,
scrollElementSelector: ".hashtag-autocomplete__fadeout",
autoSelectFirstSuggestion: true, autoSelectFirstSuggestion: true,
transformComplete: (obj) => obj.ref, transformComplete: (obj) => obj.ref,
dataSource: (term) => { dataSource: (term) => {