mirror of
https://github.com/discourse/discourse.git
synced 2024-11-23 08:09:33 +08:00
A11Y: Signal the toggle header can reorder table elements. (#18597)
While navigating the table, indicate what the button does and if the user pressed it or not. Also, don't lose focus after reordering elements.
This commit is contained in:
parent
6b4b279141
commit
2933baa0ce
|
@ -15,22 +15,24 @@
|
|||
|
||||
<LoadMore @class="users-list-container" @selector=".users-list tr" @action={{action "loadMore"}}>
|
||||
{{#if this.model}}
|
||||
<table class="table users-list grid">
|
||||
<table class="table users-list grid" role="table" aria-label={{this.title}}>
|
||||
<thead>
|
||||
<TableHeaderToggle @field="username" @labelKey="username" @order={{this.order}} @asc={{this.asc}} @automatic={{true}} />
|
||||
<TableHeaderToggle @class={{if this.showEmails "" "hidden"}} @field="email" @labelKey="email" @order={{this.order}} @asc={{this.asc}} @automatic={{true}} />
|
||||
<TableHeaderToggle @field="last_emailed" @labelKey="admin.users.last_emailed" @order={{this.order}} @asc={{this.asc}} @automatic={{true}} />
|
||||
<TableHeaderToggle @field="seen" @labelKey="last_seen" @order={{this.order}} @asc={{this.asc}} @automatic={{true}} />
|
||||
<TableHeaderToggle @field="topics_viewed" @labelKey="admin.user.topics_entered" @order={{this.order}} @asc={{this.asc}} @automatic={{true}} />
|
||||
<TableHeaderToggle @field="posts_read" @labelKey="admin.user.posts_read_count" @order={{this.order}} @asc={{this.asc}} @automatic={{true}} />
|
||||
<TableHeaderToggle @field="read_time" @labelKey="admin.user.time_read" @order={{this.order}} @asc={{this.asc}} @automatic={{true}} />
|
||||
<TableHeaderToggle @field="created" @labelKey="created" @order={{this.order}} @asc={{this.asc}} @automatic={{true}} />
|
||||
<PluginOutlet @name="admin-users-list-thead-after" @args={{hash order=this.order asc=this.asc}} />
|
||||
<tr>
|
||||
<TableHeaderToggle @field="username" @labelKey="username" @order={{this.order}} @asc={{this.asc}} @automatic={{true}} />
|
||||
<TableHeaderToggle @class={{if this.showEmails "" "hidden"}} @field="email" @labelKey="email" @order={{this.order}} @asc={{this.asc}} @automatic={{true}} />
|
||||
<TableHeaderToggle @field="last_emailed" @labelKey="admin.users.last_emailed" @order={{this.order}} @asc={{this.asc}} @automatic={{true}} />
|
||||
<TableHeaderToggle @field="seen" @labelKey="last_seen" @order={{this.order}} @asc={{this.asc}} @automatic={{true}} />
|
||||
<TableHeaderToggle @field="topics_viewed" @labelKey="admin.user.topics_entered" @order={{this.order}} @asc={{this.asc}} @automatic={{true}} />
|
||||
<TableHeaderToggle @field="posts_read" @labelKey="admin.user.posts_read_count" @order={{this.order}} @asc={{this.asc}} @automatic={{true}} />
|
||||
<TableHeaderToggle @field="read_time" @labelKey="admin.user.time_read" @order={{this.order}} @asc={{this.asc}} @automatic={{true}} />
|
||||
<TableHeaderToggle @field="created" @labelKey="created" @order={{this.order}} @asc={{this.asc}} @automatic={{true}} />
|
||||
<PluginOutlet @name="admin-users-list-thead-after" @args={{hash order=this.order asc=this.asc}} />
|
||||
|
||||
{{#if this.siteSettings.must_approve_users}}
|
||||
<th>{{i18n "admin.users.approved"}}</th>
|
||||
{{/if}}
|
||||
<th> </th>
|
||||
{{#if this.siteSettings.must_approve_users}}
|
||||
<th>{{i18n "admin.users.approved"}}</th>
|
||||
{{/if}}
|
||||
<th> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each this.model as |user|}}
|
||||
|
|
|
@ -1,18 +1,32 @@
|
|||
import Component from "@ember/component";
|
||||
import { iconHTML } from "discourse-common/lib/icon-library";
|
||||
import { htmlSafe } from "@ember/template";
|
||||
import { schedule } from "@ember/runloop";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import I18n from "I18n";
|
||||
|
||||
export default Component.extend({
|
||||
tagName: "th",
|
||||
classNames: ["sortable"],
|
||||
attributeBindings: ["title", "colspan"],
|
||||
attributeBindings: ["title", "colspan", "ariaSort:aria-sort", "role"],
|
||||
role: "columnheader",
|
||||
labelKey: null,
|
||||
chevronIcon: null,
|
||||
columnIcon: null,
|
||||
translated: false,
|
||||
automatic: false,
|
||||
onActiveRender: null,
|
||||
pressedState: null,
|
||||
ariaLabel: null,
|
||||
|
||||
@discourseComputed("order", "field", "asc")
|
||||
ariaSort() {
|
||||
if (this.order === this.field) {
|
||||
return this.asc ? "ascending" : "descending";
|
||||
} else {
|
||||
return "none";
|
||||
}
|
||||
},
|
||||
toggleProperties() {
|
||||
if (this.order === this.field) {
|
||||
this.set("asc", this.asc ? null : true);
|
||||
|
@ -43,10 +57,48 @@ export default Component.extend({
|
|||
}
|
||||
this.set("id", `table-header-toggle-${this.field.replace(/\s/g, "")}`);
|
||||
this.toggleChevron();
|
||||
this._updateA11yAttributes();
|
||||
},
|
||||
didRender() {
|
||||
if (this.onActiveRender && this.chevronIcon) {
|
||||
this.onActiveRender(this.element);
|
||||
}
|
||||
},
|
||||
_updateA11yAttributes() {
|
||||
let criteria = "";
|
||||
const pressed = this.order === this.field;
|
||||
|
||||
if (this.icon === "heart") {
|
||||
criteria += `${I18n.t("likes_lowercase", { count: 2 })} `;
|
||||
}
|
||||
|
||||
if (this.translated) {
|
||||
criteria += this.field;
|
||||
} else {
|
||||
const labelKey = this.labelKey || `directory.${this.field}`;
|
||||
|
||||
criteria += I18n.t(labelKey + "_long", {
|
||||
defaultValue: I18n.t(labelKey),
|
||||
});
|
||||
}
|
||||
|
||||
this.set("ariaLabel", I18n.t("directory.sort.label", { criteria }));
|
||||
|
||||
if (pressed) {
|
||||
if (this.asc) {
|
||||
this.set("pressedState", "mixed");
|
||||
} else {
|
||||
this.set("pressedState", "true");
|
||||
}
|
||||
|
||||
this._focusHeader();
|
||||
} else {
|
||||
this.set("pressedState", "false");
|
||||
}
|
||||
},
|
||||
_focusHeader() {
|
||||
schedule("afterRender", () => {
|
||||
document.getElementById(this.id)?.focus();
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
class="header-contents"
|
||||
id={{this.id}}
|
||||
role="button"
|
||||
tabindex="0">
|
||||
tabindex="0"
|
||||
aria-label={{this.ariaLabel}}
|
||||
aria-pressed={{this.pressedState}}>
|
||||
{{directory-table-header-title field=this.field labelKey=this.labelKey icon=this.icon translated=this.translated}}
|
||||
{{this.chevronIcon}}
|
||||
</span>
|
||||
|
|
|
@ -720,6 +720,8 @@ en:
|
|||
reset_to_default: "Reset to default"
|
||||
group:
|
||||
all: "all groups"
|
||||
sort:
|
||||
label: "Sort by %{criteria}"
|
||||
|
||||
group_histories:
|
||||
actions:
|
||||
|
|
Loading…
Reference in New Issue
Block a user