Skip to content

Commit

Permalink
[A11Y] Improve accessibility for discussion reply count on post stream (
Browse files Browse the repository at this point in the history
#3090)

* Add class to remove all UA styles from a button

* Improve classList utilisation

* Simplify JSX

* Use classlist instead of concatenation

* Fix reply count focusable when not acting as a button

* Add SR only class

* Add new reply count translations

* Use cleaner translations

* Remove unused import

* Add missing new line

* Delete Accessibility.less

* Use existing `.visually-hidden` class

* Format

* Fix locale formatting
  • Loading branch information
davwheat authored Oct 27, 2021
1 parent f66a7ef commit e0b6190
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 31 deletions.
75 changes: 45 additions & 30 deletions js/src/forum/components/DiscussionListItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import TerminalPost from './TerminalPost';
import SubtreeRetainer from '../../common/utils/SubtreeRetainer';
import DiscussionControls from '../utils/DiscussionControls';
import slidable from '../utils/slidable';
import extractText from '../../common/utils/extractText';
import classList from '../../common/utils/classList';
import DiscussionPage from './DiscussionPage';
import escapeRegExp from '../../common/utils/escapeRegExp';
Expand Down Expand Up @@ -50,12 +49,11 @@ export default class DiscussionListItem extends Component {

elementAttrs() {
return {
className: classList([
'DiscussionListItem',
this.active() ? 'active' : '',
this.attrs.discussion.isHidden() ? 'DiscussionListItem--hidden' : '',
'ontouchstart' in window ? 'Slidable' : '',
]),
className: classList('DiscussionListItem', {
active: this.active(),
'DiscussionListItem--hidden': this.attrs.discussion.isHidden(),
Slidable: 'ontouchstart' in window,
}),
};
}

Expand All @@ -64,7 +62,7 @@ export default class DiscussionListItem extends Component {
const user = discussion.user();
const isUnread = discussion.isUnread();
const isRead = discussion.isRead();
const showUnread = !this.showRepliesCount() && isUnread;

let jumpTo = 0;
const controls = DiscussionControls.controls(discussion, this).toArray();
const attrs = this.elementAttrs();
Expand All @@ -83,17 +81,16 @@ export default class DiscussionListItem extends Component {

return (
<div {...attrs}>
{controls.length
? Dropdown.component(
{
icon: 'fas fa-ellipsis-v',
className: 'DiscussionListItem-controls',
buttonClassName: 'Button Button--icon Button--flat Slidable-underneath Slidable-underneath--right',
accessibleToggleLabel: app.translator.trans('core.forum.discussion_controls.toggle_dropdown_accessible_label'),
},
controls
)
: ''}
{controls.length > 0 &&
Dropdown.component(
{
icon: 'fas fa-ellipsis-v',
className: 'DiscussionListItem-controls',
buttonClassName: 'Button Button--icon Button--flat Slidable-underneath Slidable-underneath--right',
accessibleToggleLabel: app.translator.trans('core.forum.discussion_controls.toggle_dropdown_accessible_label'),
},
controls
)}

<span
className={'Slidable-underneath Slidable-underneath--left Slidable-underneath--elastic' + (isUnread ? '' : ' disabled')}
Expand All @@ -102,7 +99,7 @@ export default class DiscussionListItem extends Component {
{icon('fas fa-check')}
</span>

<div className={'DiscussionListItem-content Slidable-content' + (isUnread ? ' unread' : '') + (isRead ? ' read' : '')}>
<div className={classList('DiscussionListItem-content', 'Slidable-content', { unread: isUnread, read: isRead })}>
<Tooltip
text={app.translator.trans('core.forum.discussion_list.started_text', { user, ago: humanTime(discussion.createdAt()) })}
position="right"
Expand All @@ -118,16 +115,7 @@ export default class DiscussionListItem extends Component {
<h3 className="DiscussionListItem-title">{highlight(discussion.title(), this.highlightRegExp)}</h3>
<ul className="DiscussionListItem-info">{listItems(this.infoItems().toArray())}</ul>
</Link>

<span
tabindex="0"
role="button"
className="DiscussionListItem-count"
onclick={this.markAsRead.bind(this)}
title={showUnread ? app.translator.trans('core.forum.discussion_list.mark_as_read_tooltip') : ''}
>
{abbreviateNumber(discussion[showUnread ? 'unreadCount' : 'replyCount']())}
</span>
{this.replyCountItem()}
</div>
</div>
);
Expand Down Expand Up @@ -222,4 +210,31 @@ export default class DiscussionListItem extends Component {

return items;
}

replyCountItem() {
const discussion = this.attrs.discussion;
const showUnread = !this.showRepliesCount() && discussion.isUnread();

if (showUnread) {
return (
<button className="Button--ua-reset DiscussionListItem-count" onclick={this.markAsRead.bind(this)}>
<span aria-hidden="true">{abbreviateNumber(discussion.unreadCount())}</span>

<span class="visually-hidden">
{app.translator.trans('core.forum.discussion_list.unread_replies_a11y_label', { count: discussion.replyCount() })}
</span>
</button>
);
}

return (
<span className="DiscussionListItem-count">
<span aria-hidden="true">{abbreviateNumber(discussion.replyCount())}</span>

<span class="visually-hidden">
{app.translator.trans('core.forum.discussion_list.total_replies_a11y_label', { count: discussion.replyCount() })}
</span>
</span>
);
}
}
33 changes: 33 additions & 0 deletions less/common/Button.less
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,36 @@
font-weight: bold;
margin-left: 10px;
}

// Remove all user-agent styles from the Button
.Button--ua-reset {
border: none;
margin: 0;
padding: 0;
width: auto;
overflow: visible;
text-align: inherit;
vertical-align: inherit;

background: transparent;

/* inherit font & color from ancestor */
color: inherit;
font: inherit;

/* Normalize `line-height`. Cannot be changed from `normal` in Firefox 4+. */
line-height: normal;

/* Corrects font smoothing for webkit */
-webkit-font-smoothing: inherit;
-moz-osx-font-smoothing: inherit;

/* Corrects inability to style clickable `input` types in iOS */
-webkit-appearance: none;
appearance: none;

&::-moz-focus-inner {
border: 0;
padding: 0;
}
}
3 changes: 2 additions & 1 deletion locale/core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -326,9 +326,10 @@ core:
discussion_list:
empty_text: It looks as though there are no discussions here.
load_more_button: => core.ref.load_more
mark_as_read_tooltip: Mark as Read
replied_text: "{username} replied {ago}"
started_text: "{username} started {ago}"
total_replies_a11y_label: "{count, plural, one {# reply} other {# replies}}"
unread_replies_a11y_label: "{count, plural, one {# unread reply} other {# unread replies}}. Mark unread {count, plural, one {reply} other {replies}} as read."

# These translations are used in the Forgot Password modal dialog.
forgot_password:
Expand Down

0 comments on commit e0b6190

Please sign in to comment.