A11Y: improve topic list table markup for screenreaders (#27808)
Co-authored-by: Jarek Radosz <jradosz@gmail.com>
This commit is contained in:
parent
aedff155bd
commit
0e3ed7ea2a
|
@ -1,3 +1,5 @@
|
|||
<caption class="sr-only">{{i18n "sr_topic_list_caption"}}</caption>
|
||||
|
||||
<thead class="topic-list-header">
|
||||
{{raw
|
||||
"topic-list-header"
|
||||
|
|
|
@ -101,6 +101,7 @@ export default class TopicList extends Component {
|
|||
(if this.bulkSelectEnabled "sticky-header")
|
||||
}}
|
||||
>
|
||||
<caption class="sr-only">{{i18n "sr_topic_list_caption"}}</caption>
|
||||
<thead class="topic-list-header">
|
||||
<TopicListHeader
|
||||
@canBulkSelect={{@canBulkSelect}}
|
||||
|
|
|
@ -66,6 +66,7 @@ export default class TopicEntrance extends Component {
|
|||
|
||||
<template>
|
||||
<DMenu
|
||||
@title={{@title}}
|
||||
@ariaLabel={{@title}}
|
||||
@placement="center"
|
||||
@autofocus={{true}}
|
||||
|
|
|
@ -83,9 +83,6 @@ export default class TopicListHeaderColumn extends Component {
|
|||
{{(if @sortable (modifier on "keydown" this.onKeyDown))}}
|
||||
data-sort-order={{@order}}
|
||||
scope="col"
|
||||
tabindex={{if @sortable "0"}}
|
||||
role={{if @sortable "button"}}
|
||||
aria-pressed={{this.isSorting}}
|
||||
aria-sort={{this.ariaSort}}
|
||||
class={{concatClass
|
||||
"topic-list-data"
|
||||
|
@ -144,7 +141,14 @@ export default class TopicListHeaderColumn extends Component {
|
|||
@changeNewListSubset={{@changeNewListSubset}}
|
||||
/>
|
||||
{{else}}
|
||||
<span>{{this.localizedName}}</span>
|
||||
<span
|
||||
class={{if @screenreaderOnly "sr-only"}}
|
||||
tabindex={{if @sortable "0"}}
|
||||
role={{if @sortable "button"}}
|
||||
aria-pressed={{this.isSorting}}
|
||||
>
|
||||
{{this.localizedName}}
|
||||
</span>
|
||||
{{/if}}
|
||||
{{/unless}}
|
||||
|
||||
|
|
|
@ -50,6 +50,8 @@ const TopicListHeader = <template>
|
|||
@activeOrder={{@order}}
|
||||
@changeSort={{@changeSort}}
|
||||
@ascending={{@ascending}}
|
||||
@name="posters"
|
||||
@screenreaderOnly={{true}}
|
||||
aria-label={{i18n "category.sort_options.posters"}}
|
||||
/>
|
||||
{{/if}}
|
||||
|
@ -62,7 +64,6 @@ const TopicListHeader = <template>
|
|||
@changeSort={{@changeSort}}
|
||||
@ascending={{@ascending}}
|
||||
@name="replies"
|
||||
aria-label={{i18n "sr_replies"}}
|
||||
/>
|
||||
|
||||
{{#if @showLikes}}
|
||||
|
@ -74,7 +75,6 @@ const TopicListHeader = <template>
|
|||
@changeSort={{@changeSort}}
|
||||
@ascending={{@ascending}}
|
||||
@name="likes"
|
||||
aria-label={{i18n "sr_likes"}}
|
||||
/>
|
||||
{{/if}}
|
||||
|
||||
|
@ -87,7 +87,6 @@ const TopicListHeader = <template>
|
|||
@changeSort={{@changeSort}}
|
||||
@ascending={{@ascending}}
|
||||
@name="likes"
|
||||
aria-label={{i18n "sr_op_likes"}}
|
||||
/>
|
||||
{{/if}}
|
||||
|
||||
|
@ -99,7 +98,6 @@ const TopicListHeader = <template>
|
|||
@changeSort={{@changeSort}}
|
||||
@ascending={{@ascending}}
|
||||
@name="views"
|
||||
aria-label={{i18n "sr_views"}}
|
||||
/>
|
||||
|
||||
<TopicListHeaderColumn
|
||||
|
@ -110,7 +108,6 @@ const TopicListHeader = <template>
|
|||
@changeSort={{@changeSort}}
|
||||
@ascending={{@ascending}}
|
||||
@name="activity"
|
||||
aria-label={{i18n "sr_activity"}}
|
||||
/>
|
||||
|
||||
<PluginOutlet @name="topic-list-header-after" />
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<{{view.tagName}} class='num posts-map posts {{view.likesHeat}} topic-list-data' title='{{view.title}}'>
|
||||
<button class="btn-link posts-map badge-posts {{view.likesHeat}}" aria-label="{{view.title}}">
|
||||
<{{view.tagName}} class='num posts-map posts {{view.likesHeat}} topic-list-data'>
|
||||
<button class="btn-link posts-map badge-posts {{view.likesHeat}}" title="{{view.title}}" aria-label="{{view.title}}">
|
||||
{{raw-plugin-outlet name="topic-list-before-reply-count"}}
|
||||
{{number topic.replyCount noTitle="true"}}
|
||||
</button>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<th data-sort-order='{{order}}' class='{{view.className}} topic-list-data' scope="col" {{#if ariaLabel}}aria-label='{{ariaLabel}}'{{/if}} {{#if sortable}}tabindex="0" role="button" aria-pressed='{{view.ariaPressed}}' {{#if view.ariaSort}}aria-sort='{{view.ariaSort}}'{{/if}} {{/if}}>
|
||||
<th data-sort-order='{{order}}' class='{{view.className}} topic-list-data' scope="col" {{#if view.ariaSort}}aria-sort='{{view.ariaSort}}'{{/if}}>
|
||||
{{~#if canBulkSelect}}
|
||||
{{~#if showBulkToggle}}
|
||||
{{~#if experimentalTopicBulkActionsEnabled }}
|
||||
|
@ -25,7 +25,7 @@
|
|||
{{~#if view.showTopicsAndRepliesToggle}}
|
||||
{{raw "list/new-list-header-controls" current=newListSubset newRepliesCount=newRepliesCount newTopicsCount=newTopicsCount}}
|
||||
{{else}}
|
||||
<span>{{view.localizedName}}</span>
|
||||
<span {{#if view.screenreaderOnly}}class="sr-only"{{/if}} {{#if sortable}}tabindex="0" role="button" aria-pressed='{{view.ariaPressed}}'{{/if}}>{{view.localizedName}}</span>
|
||||
{{/if ~}}
|
||||
{{/unless ~}}
|
||||
{{~#if view.isSorting}}
|
||||
|
|
|
@ -13,15 +13,15 @@
|
|||
{{raw "topic-list-header-column" order='default' name=listTitle bulkSelectEnabled=bulkSelectEnabled showBulkToggle=toggleInTitle canBulkSelect=canBulkSelect canDoBulkActions=canDoBulkActions showTopicsAndRepliesToggle=showTopicsAndRepliesToggle newListSubset=newListSubset newRepliesCount=newRepliesCount newTopicsCount=newTopicsCount experimentalTopicBulkActionsEnabled=experimentalTopicBulkActionsEnabled bulkSelectHelper=bulkSelectHelper }}
|
||||
{{raw-plugin-outlet name="topic-list-header-after-main-link"}}
|
||||
{{#if showPosters}}
|
||||
{{raw "topic-list-header-column" order='posters' ariaLabel=(i18n "category.sort_options.posters")}}
|
||||
{{raw "topic-list-header-column" name='posters' screenreaderOnly='true'}}
|
||||
{{/if}}
|
||||
{{raw "topic-list-header-column" sortable=sortable number='true' order='posts' name='replies' ariaLabel=(i18n "sr_replies")}}
|
||||
{{raw "topic-list-header-column" sortable=sortable number='true' order='posts' name='replies'}}
|
||||
{{#if showLikes}}
|
||||
{{raw "topic-list-header-column" sortable=sortable number='true' order='likes' name='likes' ariaLabel=(i18n "sr_likes")}}
|
||||
{{raw "topic-list-header-column" sortable=sortable number='true' order='likes' name='likes'}}
|
||||
{{/if}}
|
||||
{{#if showOpLikes}}
|
||||
{{raw "topic-list-header-column" sortable=sortable number='true' order='op_likes' name='likes' ariaLabel=(i18n "sr_op_likes")}}
|
||||
{{raw "topic-list-header-column" sortable=sortable number='true' order='op_likes' name='likes'}}
|
||||
{{/if}}
|
||||
{{raw "topic-list-header-column" sortable=sortable number='true' order='views' name='views' ariaLabel=(i18n "sr_views")}}
|
||||
{{raw "topic-list-header-column" sortable=sortable number='true' order='activity' name='activity' ariaLabel=(i18n "sr_activity")}}
|
||||
{{raw "topic-list-header-column" sortable=sortable number='true' order='views' name='views'}}
|
||||
{{raw "topic-list-header-column" sortable=sortable number='true' order='activity' name='activity'}}
|
||||
{{~raw-plugin-outlet name="topic-list-header-after"~}}
|
||||
|
|
|
@ -19,7 +19,10 @@ export default EmberObject.extend({
|
|||
|
||||
@discourseComputed("topic.replyCount", "ratioText")
|
||||
title(count, ratio) {
|
||||
return I18n.messageFormat("posts_likes_MF", { count, ratio }).trim();
|
||||
return I18n.messageFormat("posts_likes_MF", {
|
||||
count,
|
||||
ratio,
|
||||
});
|
||||
},
|
||||
|
||||
@discourseComputed("ratio")
|
||||
|
|
|
@ -4141,36 +4141,33 @@ en:
|
|||
pending_posts:
|
||||
label: "Pending"
|
||||
label_with_count: "Pending (%{count})"
|
||||
sr_topic_list_caption: Topic list, column headers with buttons are sortable.
|
||||
|
||||
# This string uses the ICU Message Format. See https://meta.discourse.org/t/7035 for translation guidelines.
|
||||
posts_likes_MF: |
|
||||
This topic has { count, plural,
|
||||
one {# reply}
|
||||
other {# replies}
|
||||
} { ratio, select,
|
||||
low {with a high like to post ratio}
|
||||
med {with a very high like to post ratio}
|
||||
high {with an extremely high like to post ratio}
|
||||
{ count, plural,
|
||||
one {# reply,}
|
||||
other {# replies,}
|
||||
}{ ratio, select,
|
||||
low { high like to post ratio,}
|
||||
med { very high like to post ratio,}
|
||||
high { extremely high like to post ratio,}
|
||||
other {}
|
||||
}
|
||||
} jump to the first or last post…
|
||||
|
||||
posters: "Posters"
|
||||
latest_poster_link: "%{username}'s profile, latest poster"
|
||||
original_post: "Original Post"
|
||||
views: "Views"
|
||||
sr_views: "Sort by views"
|
||||
views_lowercase:
|
||||
one: "view"
|
||||
other: "views"
|
||||
replies: "Replies"
|
||||
sr_replies: "Sort by replies"
|
||||
views_long:
|
||||
one: "this topic has been viewed %{count} time"
|
||||
other: "this topic has been viewed %{count} times"
|
||||
activity: "Activity"
|
||||
sr_activity: "Sort by activity"
|
||||
likes: "Likes"
|
||||
sr_likes: "Sort by likes"
|
||||
sr_op_likes: "Sort by original post likes"
|
||||
likes_lowercase:
|
||||
one: "like"
|
||||
other: "likes"
|
||||
|
|
|
@ -172,7 +172,7 @@ RSpec.describe JsLocaleHelper do
|
|||
it "translates messages properly" do
|
||||
expect(
|
||||
translated_message,
|
||||
).to eq "This topic has 3 replies with a very high like to post ratio\n"
|
||||
).to eq "3 replies, very high like to post ratio, jump to the first or last post…\n"
|
||||
end
|
||||
|
||||
context "when the translation is overriden" do
|
||||
|
@ -207,7 +207,7 @@ RSpec.describe JsLocaleHelper do
|
|||
it "returns the fallback translation" do
|
||||
expect(
|
||||
translated_message,
|
||||
).to eq "This topic has 3 replies with a very high like to post ratio\n"
|
||||
).to eq "3 replies, very high like to post ratio, jump to the first or last post…\n"
|
||||
end
|
||||
|
||||
context "when the fallback translation is overriden" do
|
||||
|
|
Loading…
Reference in New Issue