UX: Allow select-kit to have an autofocus option (#12183)
On some modals the main/primary input field is a select-kit component (like {{email-group-user-chooser}}
on the assign modal), so it makes sense to allow select-kit to steal focus on modals like these. This PR adds an autofocus
option (default false) that allows select-kit to steal focus when it’s rendered.
diff --git a/app/assets/javascripts/discourse/tests/integration/components/select-kit/email-group-user-chooser-test.js b/app/assets/javascripts/discourse/tests/integration/components/select-kit/email-group-user-chooser-test.js
new file mode 100644
index 0000000..78b122d
--- /dev/null
+++ b/app/assets/javascripts/discourse/tests/integration/components/select-kit/email-group-user-chooser-test.js
@@ -0,0 +1,64 @@
+import componentTest, {
+ setupRenderingTest,
+} from "discourse/tests/helpers/component-test";
+import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
+import hbs from "htmlbars-inline-precompile";
+import selectKit from "discourse/tests/helpers/select-kit-helper";
+
+discourseModule(
+ "Integration | Component | select-kit/email-group-user-chooser",
+ function (hooks) {
+ setupRenderingTest(hooks);
+
+ hooks.beforeEach(function () {
+ this.set("subject", selectKit());
+ this.setProperties({
+ value: [],
+ onChange() {},
+ });
+ });
+
+ componentTest("autofocus option set to true", {
+ template: hbs`{{email-group-user-chooser
+ value=value
+ onChange=onChange
+ options=(hash
+ autofocus=true
+ )
+ }}`,
+
+ async test(assert) {
+ this.subject;
+ assert.ok(
+ this.subject.header().el()[0].classList.contains("is-focused"),
+ "select-kit header has is-focused class"
+ );
+ assert.ok(
+ this.subject.filter().el()[0].querySelector(".filter-input")
+ .autofocus,
+ "filter input has autofocus attribute"
+ );
+ },
+ });
+
+ componentTest("without autofocus", {
+ template: hbs`{{email-group-user-chooser
+ value=value
+ onChange=onChange
+ }}`,
+
+ async test(assert) {
+ this.subject;
+ assert.ok(
+ !this.subject.header().el()[0].classList.contains("is-focused"),
+ "select-kit header doesn't have is-focused class"
+ );
+ assert.ok(
+ !this.subject.filter().el()[0].querySelector(".filter-input")
+ .autofocus,
+ "filter input doesn't have autofocus attribute"
+ );
+ },
+ });
+ }
+);
diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit.js b/app/assets/javascripts/select-kit/addon/components/select-kit.js
index 663776d..2a4d276 100644
--- a/app/assets/javascripts/select-kit/addon/components/select-kit.js
+++ b/app/assets/javascripts/select-kit/addon/components/select-kit.js
@@ -280,6 +280,7 @@ export default Component.extend(
preventsClickPropagation: false,
focusAfterOnChange: true,
triggerOnChangeOnTab: true,
+ autofocus: false,
},
autoFilterable: computed("content.[]", "selectKit.filter", function () {
diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-header.js b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-header.js
index 2525e43..0d389c9 100644
--- a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-header.js
+++ b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-header.js
@@ -76,6 +76,13 @@ export default Component.extend(UtilsMixin, {
tabindex: 0,
+ didInsertElement() {
+ this._super(...arguments);
+ if (this.selectKit.options.autofocus) {
+ this.set("isFocused", true);
+ }
+ },
+
keyUp(event) {
if (event.keyCode === 32) {
event.preventDefault();
diff --git a/app/assets/javascripts/select-kit/addon/templates/components/select-kit/select-kit-filter.hbs b/app/assets/javascripts/select-kit/addon/templates/components/select-kit/select-kit-filter.hbs
index d67c68e..9927703 100644
--- a/app/assets/javascripts/select-kit/addon/templates/components/select-kit/select-kit-filter.hbs
+++ b/app/assets/javascripts/select-kit/addon/templates/components/select-kit/select-kit-filter.hbs
@@ -6,6 +6,7 @@
autocomplete="discourse"
autocorrect="off"
autocapitalize="off"
+ autofocus=selectKit.options.autofocus
spellcheck=false
value=(readonly selectKit.filter)
input=(action "onInput")
GitHub sha: 0f807ba8