DEV: allows buttons to define aria-label (#9747)

This commit is contained in:
Joffrey JAFFEUX 2020-05-11 22:09:44 +02:00 committed by GitHub
parent b4bd238dd6
commit 286b4e535e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 114 additions and 27 deletions

View File

@ -5,12 +5,17 @@ import discourseComputed from "discourse-common/utils/decorators";
import DiscourseURL from "discourse/lib/url"; import DiscourseURL from "discourse/lib/url";
export default Component.extend({ export default Component.extend({
tagName: "button",
// subclasses need this // subclasses need this
layoutName: "components/d-button", layoutName: "components/d-button",
form: null, form: null,
type: "button", type: "button",
title: null,
translatedTitle: null,
label: null,
translatedLabel: null,
ariaLabel: null,
translatedAriaLabel: null,
isLoading: computed({ isLoading: computed({
set(key, value) { set(key, value) {
@ -19,7 +24,6 @@ export default Component.extend({
} }
}), }),
tagName: "button",
classNameBindings: [ classNameBindings: [
"isLoading:is-loading", "isLoading:is-loading",
"btnLink::btn", "btnLink::btn",
@ -30,8 +34,8 @@ export default Component.extend({
attributeBindings: [ attributeBindings: [
"form", "form",
"isDisabled:disabled", "isDisabled:disabled",
"translatedTitle:title", "computedTitle:title",
"translatedLabel:aria-label", "computedAriaLabel:aria-label",
"tabindex", "tabindex",
"type" "type"
], ],
@ -46,7 +50,7 @@ export default Component.extend({
btnLink: equal("display", "link"), btnLink: equal("display", "link"),
@discourseComputed("icon", "translatedLabel") @discourseComputed("icon", "computedLabel")
btnType(icon, translatedLabel) { btnType(icon, translatedLabel) {
if (icon) { if (icon) {
return translatedLabel ? "btn-icon-text" : "btn-icon"; return translatedLabel ? "btn-icon-text" : "btn-icon";
@ -55,28 +59,25 @@ export default Component.extend({
} }
}, },
noText: empty("translatedLabel"), noText: empty("computedLabel"),
@discourseComputed("title") @discourseComputed("title", "translatedTitle")
translatedTitle: { computedTitle(title, translatedTitle) {
get() { if (this.title) return I18n.t(title);
if (this._translatedTitle) return this._translatedTitle; return translatedTitle;
if (this.title) return I18n.t(this.title);
},
set(value) {
return (this._translatedTitle = value);
}
}, },
@discourseComputed("label") @discourseComputed("label", "translatedLabel")
translatedLabel: { computedLabel(label, translatedLabel) {
get() { if (this.label) return I18n.t(label);
if (this._translatedLabel) return this._translatedLabel; return translatedLabel;
if (this.label) return I18n.t(this.label); },
},
set(value) { @discourseComputed("ariaLabel", "translatedAriaLabel", "computedLabel")
return (this._translatedLabel = value); computedAriaLabel(ariaLabel, translatedAriaLabel, computedLabel) {
} if (ariaLabel) return I18n.t(ariaLabel);
if (translatedAriaLabel) return translatedAriaLabel;
return computedLabel;
}, },
click() { click() {

View File

@ -28,6 +28,10 @@ export function registerTopicFooterButton(button) {
label: null, label: null,
translatedLabel: 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 ? // is this button disaplyed in the mobile dropdown or as an inline button ?
dropdown: false, dropdown: false,
@ -98,6 +102,15 @@ export function getTopicFooterButtons() {
? I18n.t(label) ? I18n.t(label)
: _compute(button, "translatedLabel"); : _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"); const title = _compute(button, "title");
discourseComputedButon.title = title discourseComputedButon.title = title
? I18n.t(title) ? I18n.t(title)

View File

@ -10,8 +10,8 @@
{{/if}} {{/if}}
{{/if}} {{/if}}
{{#if translatedLabel}} {{#if computedLabel}}
<span class="d-button-label">{{html-safe translatedLabel}}{{#if ellipsis}}&hellip;{{/if}}</span> <span class="d-button-label">{{html-safe computedLabel}}{{#if ellipsis}}&hellip;{{/if}}</span>
{{/if}} {{/if}}
{{yield}} {{yield}}

View File

@ -29,6 +29,7 @@
icon=button.icon icon=button.icon
translatedLabel=button.label translatedLabel=button.label
translatedTitle=button.title translatedTitle=button.title
translatedAriaLabel=button.ariaLabel
disabled=button.disabled}} disabled=button.disabled}}
{{/each}} {{/each}}

View File

@ -100,3 +100,75 @@ componentTest("disabled button", {
assert.ok(find("button:not([disabled])").length, "the button is enabled"); 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");
}
});