Skip to content

Commit fd4cdd0

Browse files
committed
Improve A11Y of timeline. Show TS & Actions on focus-within
1 parent db0e643 commit fd4cdd0

File tree

6 files changed

+18
-6
lines changed

6 files changed

+18
-6
lines changed

res/css/views/rooms/_EventTile.scss

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,13 @@ limitations under the License.
138138
// Explicit relationships so that it doesn't apply to nested EventTile components (e.g in Replies)
139139
.mx_EventTile_last > div > a > .mx_MessageTimestamp,
140140
.mx_EventTile:hover > div > a > .mx_MessageTimestamp,
141+
.mx_EventTile:focus-within > div > a > .mx_MessageTimestamp,
141142
.mx_EventTile.mx_EventTile_actionBarFocused > div > a > .mx_MessageTimestamp {
142143
visibility: visible;
143144
}
144145

145146
.mx_EventTile:hover .mx_MessageActionBar,
147+
.mx_EventTile:focus-within .mx_MessageActionBar,
146148
.mx_EventTile.mx_EventTile_actionBarFocused .mx_MessageActionBar {
147149
visibility: visible;
148150
}
@@ -166,6 +168,7 @@ limitations under the License.
166168
}
167169

168170
.mx_EventTile:hover .mx_EventTile_line,
171+
.mx_EventTile:focus-within .mx_EventTile_line,
169172
.mx_EventTile.mx_EventTile_actionBarFocused .mx_EventTile_line {
170173
background-color: $event-selected-color;
171174
}
@@ -465,7 +468,8 @@ div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody {
465468
}
466469
}
467470

468-
.mx_EventTile:hover .mx_EventTile_body pre {
471+
.mx_EventTile:hover .mx_EventTile_body pre,
472+
.mx_EventTile:focus-within .mx_EventTile_body pre {
469473
border: 1px solid #e5e5e5; // deliberate constant as we're behind an invert filter
470474
}
471475

@@ -487,6 +491,7 @@ div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody {
487491
background-image: url($copy-button-url);
488492
}
489493

494+
.mx_EventTile_body .mx_EventTile_pre_container:focus-within .mx_EventTile_copyButton,
490495
.mx_EventTile_body .mx_EventTile_pre_container:hover .mx_EventTile_copyButton {
491496
visibility: visible;
492497
}

src/components/views/messages/DateSeparator.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export default class DateSeparator extends React.Component {
5757

5858
render() {
5959
// ARIA treats <hr/>s as separators, here we abuse them slightly so manually treat this entire thing as one
60-
return <h2 className="mx_DateSeparator" role="separator">
60+
return <h2 className="mx_DateSeparator" role="separator" tabIndex={-1}>
6161
<hr role="none" />
6262
<div>{ this.getLabel() }</div>
6363
<hr role="none" />

src/components/views/messages/MessageActionBar.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ export default class MessageActionBar extends React.PureComponent {
180180
/>;
181181
}
182182

183-
return <div className="mx_MessageActionBar">
183+
// aria-live=off to not have this read out automatically as navigating around timeline, gets repetitive.
184+
return <div className="mx_MessageActionBar" role="toolbar" aria-label={_t("Message Actions")} aria-live="off">
184185
{reactButton}
185186
{replyButton}
186187
{editButton}

src/components/views/messages/MessageTimestamp.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export default class MessageTimestamp extends React.Component {
2828
render() {
2929
const date = new Date(this.props.ts);
3030
return (
31-
<span className="mx_MessageTimestamp" title={formatFullDate(date, this.props.showTwelveHour)}>
31+
<span className="mx_MessageTimestamp" title={formatFullDate(date, this.props.showTwelveHour)} aria-hidden={true}>
3232
{ formatTime(date, this.props.showTwelveHour) }
3333
</span>
3434
);

src/components/views/rooms/EventTile.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const TextForEvent = require('../../../TextForEvent');
3232
import dis from '../../../dispatcher';
3333
import SettingsStore from "../../../settings/SettingsStore";
3434
import {EventStatus, MatrixClient} from 'matrix-js-sdk';
35+
import {formatTime} from "../../../DateUtils";
3536

3637
const ObjectUtils = require('../../../ObjectUtils');
3738

@@ -787,13 +788,17 @@ module.exports = createReactClass({
787788
'replyThread',
788789
);
789790
return (
790-
<div className={classes}>
791+
<div className={classes} tabIndex={-1}>
791792
<div className="mx_EventTile_msgOption">
792793
{ readAvatars }
793794
</div>
794795
{ sender }
795796
<div className="mx_EventTile_line">
796-
<a href={permalink} onClick={this.onPermalinkClicked}>
797+
<a
798+
href={permalink}
799+
onClick={this.onPermalinkClicked}
800+
aria-label={formatTime(new Date(this.props.mxEvent.getTs()), this.props.isTwelveHour)}
801+
>
797802
{ timestamp }
798803
</a>
799804
{ this._renderE2EPadlock() }

src/i18n/strings/en_EN.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,7 @@
10531053
"React": "React",
10541054
"Reply": "Reply",
10551055
"Edit": "Edit",
1056+
"Message Actions": "Message Actions",
10561057
"Options": "Options",
10571058
"Attachment": "Attachment",
10581059
"Error decrypting attachment": "Error decrypting attachment",

0 commit comments

Comments
 (0)