diff --git a/app/assets/javascripts/discourse/app/helpers/concat-class.js b/app/assets/javascripts/discourse/app/helpers/concat-class.js
new file mode 100644
index 00000000000..d8c91ec6a2b
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/helpers/concat-class.js
@@ -0,0 +1,8 @@
+import { helper } from "@ember/component/helper";
+
+function concatClass(args) {
+ const classes = args.compact().join(" ");
+ return classes.length ? classes : undefined;
+}
+
+export default helper(concatClass);
diff --git a/app/assets/javascripts/discourse/tests/integration/helpers/concat-class-test.js b/app/assets/javascripts/discourse/tests/integration/helpers/concat-class-test.js
new file mode 100644
index 00000000000..c70528deb72
--- /dev/null
+++ b/app/assets/javascripts/discourse/tests/integration/helpers/concat-class-test.js
@@ -0,0 +1,44 @@
+import { assert, module, test } from "qunit";
+import { setupRenderingTest } from "discourse/tests/helpers/component-test";
+import { render } from "@ember/test-helpers";
+import { hbs } from "ember-cli-htmlbars";
+import { query } from "discourse/tests/helpers/qunit-helpers";
+
+module("Integration | Helper | concat-class", function (hooks) {
+ setupRenderingTest(hooks);
+
+ test("One class given", async function () {
+ await render(hbs``);
+
+ assert.equal(query("button").className, "foo");
+ });
+
+ test("Multiple class given", async function () {
+ this.set("bar", "bar");
+ await render(hbs``);
+
+ assert.equal(query("button").className, "foo bar");
+ });
+
+ test("One undefined class given", async function () {
+ this.set("bar", null);
+ await render(hbs``);
+
+ assert.equal(query("button").className, "foo");
+ });
+
+ test("Only undefined class given", async function () {
+ this.set("bar", null);
+ await render(hbs``);
+
+ assert.notOk(query("button").hasAttribute("class"));
+ });
+
+ test("Helpers used", async function () {
+ await render(
+ hbs``
+ );
+
+ assert.equal(query("button").className, "foo bar");
+ });
+});