diff --git a/app/assets/javascripts/discourse/app/components/d-editor.js b/app/assets/javascripts/discourse/app/components/d-editor.js index 64175e030fa..a622955b4c6 100644 --- a/app/assets/javascripts/discourse/app/components/d-editor.js +++ b/app/assets/javascripts/discourse/app/components/d-editor.js @@ -464,9 +464,11 @@ export default Component.extend(TextareaTextManipulation, { this.site.hashtag_configurations["topic-composer"], this._$textarea, this.siteSettings, - (value) => { - this.set("value", value); - schedule("afterRender", this, this.focusTextArea); + { + afterComplete: (value) => { + this.set("value", value); + schedule("afterRender", this, this.focusTextArea); + }, } ); }, diff --git a/app/assets/javascripts/discourse/app/lib/hashtag-autocomplete.js b/app/assets/javascripts/discourse/app/lib/hashtag-autocomplete.js index 14b6e870a25..4d7129ea0c0 100644 --- a/app/assets/javascripts/discourse/app/lib/hashtag-autocomplete.js +++ b/app/assets/javascripts/discourse/app/lib/hashtag-autocomplete.js @@ -27,23 +27,30 @@ import { htmlSafe } from "@ember/template"; * @param {$Element} $textarea - jQuery element to use for the autocompletion * plugin to attach to, this is what will watch for the # matcher when the user is typing. * @param {Hash} siteSettings - The clientside site settings. - * @param {Function} afterComplete - Called with the selected autocomplete option once it is selected. + * @param {Function} autocompleteOptions - Options to pass to the jQuery plugin. Must at least include: + * + * - afterComplete - Called with the selected autocomplete option once it is selected. + * + * Can also include: + * + * - treatAsTextarea - Whether to anchor the autocompletion to the start of the input and + * ensure the popper is always on top. **/ export function setupHashtagAutocomplete( contextualHashtagConfiguration, $textArea, siteSettings, - afterComplete + autocompleteOptions = {} ) { if (siteSettings.enable_experimental_hashtag_autocomplete) { _setupExperimental( contextualHashtagConfiguration, $textArea, siteSettings, - afterComplete + autocompleteOptions ); } else { - _setup($textArea, siteSettings, afterComplete); + _setup($textArea, siteSettings, autocompleteOptions.afterComplete); } } @@ -123,13 +130,14 @@ function _setupExperimental( contextualHashtagConfiguration, $textArea, siteSettings, - afterComplete + autocompleteOptions ) { $textArea.autocomplete({ template: findRawTemplate("hashtag-autocomplete"), key: "#", - afterComplete, - treatAsTextarea: $textArea[0].tagName === "INPUT", + afterComplete: autocompleteOptions.afterComplete, + treatAsTextarea: autocompleteOptions.treatAsTextarea, + autoSelectFirstSuggestion: true, transformComplete: (obj) => obj.ref, dataSource: (term) => { if (term.match(/\s/)) { diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-composer.js b/plugins/chat/assets/javascripts/discourse/components/chat-composer.js index 0edc60c7607..1ce08f09700 100644 --- a/plugins/chat/assets/javascripts/discourse/components/chat-composer.js +++ b/plugins/chat/assets/javascripts/discourse/components/chat-composer.js @@ -410,9 +410,12 @@ export default Component.extend(TextareaTextManipulation, { this.site.hashtag_configurations["chat-composer"], $textarea, this.siteSettings, - (value) => { - this.set("value", value); - return this._focusTextArea(); + { + treatAsTextarea: true, + afterComplete: (value) => { + this.set("value", value); + return this._focusTextArea(); + }, } ); },