mirror of
https://github.com/discourse/discourse.git
synced 2025-09-06 10:50:21 +08:00
A11Y: Make input popup errors keyboard-accessible (#18570)
Also sets focus to the nearest input when popups are dismissed.
This commit is contained in:
parent
74a6a868d2
commit
c81763dcd8
2 changed files with 32 additions and 5 deletions
|
@ -5,13 +5,15 @@ import { getOwner } from "discourse-common/lib/get-owner";
|
||||||
import { htmlSafe } from "@ember/template";
|
import { htmlSafe } from "@ember/template";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
|
tagName: "a",
|
||||||
classNameBindings: [":popup-tip", "good", "bad", "lastShownAt::hide"],
|
classNameBindings: [":popup-tip", "good", "bad", "lastShownAt::hide"],
|
||||||
attributeBindings: ["role", "ariaLabel"],
|
attributeBindings: ["role", "ariaLabel", "tabindex"],
|
||||||
rerenderTriggers: ["validation.reason"],
|
rerenderTriggers: ["validation.reason"],
|
||||||
tipReason: null,
|
tipReason: null,
|
||||||
lastShownAt: or("shownAt", "validation.lastShownAt"),
|
lastShownAt: or("shownAt", "validation.lastShownAt"),
|
||||||
bad: reads("validation.failed"),
|
bad: reads("validation.failed"),
|
||||||
good: not("bad"),
|
good: not("bad"),
|
||||||
|
tabindex: "0",
|
||||||
|
|
||||||
@discourseComputed("bad")
|
@discourseComputed("bad")
|
||||||
role(bad) {
|
role(bad) {
|
||||||
|
@ -25,10 +27,21 @@ export default Component.extend({
|
||||||
return reason?.replace(/(<([^>]+)>)/gi, "");
|
return reason?.replace(/(<([^>]+)>)/gi, "");
|
||||||
},
|
},
|
||||||
|
|
||||||
click() {
|
dismiss() {
|
||||||
this.set("shownAt", null);
|
this.set("shownAt", null);
|
||||||
const composer = getOwner(this).lookup("controller:composer");
|
const composer = getOwner(this).lookup("controller:composer");
|
||||||
composer.clearLastValidatedAt();
|
composer.clearLastValidatedAt();
|
||||||
|
this.element.previousElementSibling?.focus();
|
||||||
|
},
|
||||||
|
|
||||||
|
click() {
|
||||||
|
this.dismiss();
|
||||||
|
},
|
||||||
|
|
||||||
|
keyDown(event) {
|
||||||
|
if (event.key === "Enter") {
|
||||||
|
this.dismiss();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
didReceiveAttrs() {
|
didReceiveAttrs() {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import {
|
||||||
fillIn,
|
fillIn,
|
||||||
settled,
|
settled,
|
||||||
triggerEvent,
|
triggerEvent,
|
||||||
|
triggerKeyEvent,
|
||||||
visit,
|
visit,
|
||||||
} from "@ember/test-helpers";
|
} from "@ember/test-helpers";
|
||||||
import { toggleCheckDraftPopup } from "discourse/controllers/composer";
|
import { toggleCheckDraftPopup } from "discourse/controllers/composer";
|
||||||
|
@ -176,16 +177,29 @@ acceptance("Composer", function (needs) {
|
||||||
|
|
||||||
await click("#reply-control button.create");
|
await click("#reply-control button.create");
|
||||||
assert.ok(
|
assert.ok(
|
||||||
!exists(".title-input .popup-tip.bad.hide"),
|
exists(".title-input .popup-tip.bad"),
|
||||||
"it shows the empty title error"
|
"it shows the empty title error"
|
||||||
);
|
);
|
||||||
assert.ok(
|
assert.ok(
|
||||||
!exists(".d-editor-wrapper .popup-tip.bad.hide"),
|
exists(".d-editor-textarea-wrapper .popup-tip.bad"),
|
||||||
"it shows the empty body error"
|
"it shows the empty body error"
|
||||||
);
|
);
|
||||||
|
|
||||||
await fillIn("#reply-title", "this is my new topic title");
|
await fillIn("#reply-title", "this is my new topic title");
|
||||||
assert.ok(exists(".title-input .popup-tip.good"), "the title is now good");
|
assert.ok(
|
||||||
|
exists(".title-input .popup-tip.good.hide"),
|
||||||
|
"the title is now good"
|
||||||
|
);
|
||||||
|
|
||||||
|
await triggerKeyEvent(
|
||||||
|
".d-editor-textarea-wrapper .popup-tip.bad",
|
||||||
|
"keydown",
|
||||||
|
"Enter"
|
||||||
|
);
|
||||||
|
assert.ok(
|
||||||
|
exists(".d-editor-textarea-wrapper .popup-tip.bad.hide"),
|
||||||
|
"body error is dismissed via keyboard"
|
||||||
|
);
|
||||||
|
|
||||||
await fillIn(".d-editor-input", "this is the *content* of a post");
|
await fillIn(".d-editor-input", "this is the *content* of a post");
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue