diff --git a/app/assets/javascripts/discourse/app/components/d-button.js b/app/assets/javascripts/discourse/app/components/d-button.js
index 4df816a3474..ad4d32a5a24 100644
--- a/app/assets/javascripts/discourse/app/components/d-button.js
+++ b/app/assets/javascripts/discourse/app/components/d-button.js
@@ -5,12 +5,17 @@ import discourseComputed from "discourse-common/utils/decorators";
import DiscourseURL from "discourse/lib/url";
export default Component.extend({
+ tagName: "button",
// subclasses need this
layoutName: "components/d-button",
-
form: null,
-
type: "button",
+ title: null,
+ translatedTitle: null,
+ label: null,
+ translatedLabel: null,
+ ariaLabel: null,
+ translatedAriaLabel: null,
isLoading: computed({
set(key, value) {
@@ -19,7 +24,6 @@ export default Component.extend({
}
}),
- tagName: "button",
classNameBindings: [
"isLoading:is-loading",
"btnLink::btn",
@@ -30,8 +34,8 @@ export default Component.extend({
attributeBindings: [
"form",
"isDisabled:disabled",
- "translatedTitle:title",
- "translatedLabel:aria-label",
+ "computedTitle:title",
+ "computedAriaLabel:aria-label",
"tabindex",
"type"
],
@@ -46,7 +50,7 @@ export default Component.extend({
btnLink: equal("display", "link"),
- @discourseComputed("icon", "translatedLabel")
+ @discourseComputed("icon", "computedLabel")
btnType(icon, translatedLabel) {
if (icon) {
return translatedLabel ? "btn-icon-text" : "btn-icon";
@@ -55,28 +59,25 @@ export default Component.extend({
}
},
- noText: empty("translatedLabel"),
+ noText: empty("computedLabel"),
- @discourseComputed("title")
- translatedTitle: {
- get() {
- if (this._translatedTitle) return this._translatedTitle;
- if (this.title) return I18n.t(this.title);
- },
- set(value) {
- return (this._translatedTitle = value);
- }
+ @discourseComputed("title", "translatedTitle")
+ computedTitle(title, translatedTitle) {
+ if (this.title) return I18n.t(title);
+ return translatedTitle;
},
- @discourseComputed("label")
- translatedLabel: {
- get() {
- if (this._translatedLabel) return this._translatedLabel;
- if (this.label) return I18n.t(this.label);
- },
- set(value) {
- return (this._translatedLabel = value);
- }
+ @discourseComputed("label", "translatedLabel")
+ computedLabel(label, translatedLabel) {
+ if (this.label) return I18n.t(label);
+ return translatedLabel;
+ },
+
+ @discourseComputed("ariaLabel", "translatedAriaLabel", "computedLabel")
+ computedAriaLabel(ariaLabel, translatedAriaLabel, computedLabel) {
+ if (ariaLabel) return I18n.t(ariaLabel);
+ if (translatedAriaLabel) return translatedAriaLabel;
+ return computedLabel;
},
click() {
diff --git a/app/assets/javascripts/discourse/app/lib/register-topic-footer-button.js b/app/assets/javascripts/discourse/app/lib/register-topic-footer-button.js
index c2dd9eb96cf..ecac09a89a2 100644
--- a/app/assets/javascripts/discourse/app/lib/register-topic-footer-button.js
+++ b/app/assets/javascripts/discourse/app/lib/register-topic-footer-button.js
@@ -28,6 +28,10 @@ export function registerTopicFooterButton(button) {
label: null,
translatedLabel: null,
+ // local key path for aria label
+ ariaLabel: null,
+ translatedAriaLabel: null,
+
// is this button disaplyed in the mobile dropdown or as an inline button ?
dropdown: false,
@@ -98,6 +102,15 @@ export function getTopicFooterButtons() {
? I18n.t(label)
: _compute(button, "translatedLabel");
+ const ariaLabel = _compute(button, "ariaLabel");
+ if (ariaLabel) {
+ discourseComputedButon.ariaLabel = I18n.t(ariaLabel);
+ } else {
+ const translatedAriaLabel = _compute(button, "translatedAriaLabel");
+ discourseComputedButon.ariaLabel =
+ translatedAriaLabel || discourseComputedButon.label;
+ }
+
const title = _compute(button, "title");
discourseComputedButon.title = title
? I18n.t(title)
diff --git a/app/assets/javascripts/discourse/app/templates/components/d-button.hbs b/app/assets/javascripts/discourse/app/templates/components/d-button.hbs
index 6c9ed400751..10d12b4d836 100644
--- a/app/assets/javascripts/discourse/app/templates/components/d-button.hbs
+++ b/app/assets/javascripts/discourse/app/templates/components/d-button.hbs
@@ -10,8 +10,8 @@
{{/if}}
{{/if}}
-{{#if translatedLabel}}
- {{html-safe translatedLabel}}{{#if ellipsis}}…{{/if}}
+{{#if computedLabel}}
+ {{html-safe computedLabel}}{{#if ellipsis}}…{{/if}}
{{/if}}
{{yield}}
diff --git a/app/assets/javascripts/discourse/app/templates/components/topic-footer-buttons.hbs b/app/assets/javascripts/discourse/app/templates/components/topic-footer-buttons.hbs
index 766ae9bf2b0..007ec9c19d2 100644
--- a/app/assets/javascripts/discourse/app/templates/components/topic-footer-buttons.hbs
+++ b/app/assets/javascripts/discourse/app/templates/components/topic-footer-buttons.hbs
@@ -29,6 +29,7 @@
icon=button.icon
translatedLabel=button.label
translatedTitle=button.title
+ translatedAriaLabel=button.ariaLabel
disabled=button.disabled}}
{{/each}}
diff --git a/test/javascripts/components/d-button-test.js b/test/javascripts/components/d-button-test.js
index 5b0bdeb150b..1d85d922c4e 100644
--- a/test/javascripts/components/d-button-test.js
+++ b/test/javascripts/components/d-button-test.js
@@ -100,3 +100,75 @@ componentTest("disabled button", {
assert.ok(find("button:not([disabled])").length, "the button is enabled");
}
});
+
+componentTest("aria-label", {
+ template:
+ "{{d-button ariaLabel=ariaLabel translatedAriaLabel=translatedAriaLabel}}",
+
+ beforeEach() {
+ I18n.translations[I18n.locale].js.test = { fooAriaLabel: "foo" };
+ },
+
+ test(assert) {
+ this.set("ariaLabel", "test.fooAriaLabel");
+
+ assert.equal(
+ find("button")[0].getAttribute("aria-label"),
+ I18n.t("test.fooAriaLabel")
+ );
+
+ this.setProperties({
+ ariaLabel: null,
+ translatedAriaLabel: "bar"
+ });
+
+ assert.equal(find("button")[0].getAttribute("aria-label"), "bar");
+ }
+});
+
+componentTest("title", {
+ template: "{{d-button title=title translatedTitle=translatedTitle}}",
+
+ beforeEach() {
+ I18n.translations[I18n.locale].js.test = { fooTitle: "foo" };
+ },
+
+ test(assert) {
+ this.set("title", "test.fooTitle");
+ assert.equal(
+ find("button")[0].getAttribute("title"),
+ I18n.t("test.fooTitle")
+ );
+
+ this.setProperties({
+ title: null,
+ translatedTitle: "bar"
+ });
+
+ assert.equal(find("button")[0].getAttribute("title"), "bar");
+ }
+});
+
+componentTest("label", {
+ template: "{{d-button label=label translatedLabel=translatedLabel}}",
+
+ beforeEach() {
+ I18n.translations[I18n.locale].js.test = { fooLabel: "foo" };
+ },
+
+ test(assert) {
+ this.set("label", "test.fooLabel");
+
+ assert.equal(
+ find("button .d-button-label").text(),
+ I18n.t("test.fooLabel")
+ );
+
+ this.setProperties({
+ label: null,
+ translatedLabel: "bar"
+ });
+
+ assert.equal(find("button .d-button-label").text(), "bar");
+ }
+});