Various ARIA a11y fixes.
Notate RightPanel tabs. Shorten Screen Reader queues. Make AccessibleTooltipButton screen reader friendly Flatten DOM for Sticker button using React Fragments Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
b94c94db04
commit
f1db0cf027
16 changed files with 62 additions and 57 deletions
|
@ -126,11 +126,12 @@ const FilePanel = createReactClass({
|
|||
tileShape="file_grid"
|
||||
resizeNotifier={this.props.resizeNotifier}
|
||||
empty={_t('There are no visible files in this room')}
|
||||
role="tabpanel"
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className="mx_FilePanel">
|
||||
<div className="mx_FilePanel" role="tabpanel">
|
||||
<Loader />
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -46,12 +46,13 @@ const NotificationPanel = createReactClass({
|
|||
showUrlPreview={false}
|
||||
tileShape="notif"
|
||||
empty={_t('You have no visible notifications')}
|
||||
role="tabpanel"
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
console.error("No notifTimelineSet available!");
|
||||
return (
|
||||
<div className="mx_NotificationPanel">
|
||||
<div className="mx_NotificationPanel" role="tabpanel">
|
||||
<Loader />
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -258,7 +258,7 @@ const RoomSubList = createReactClass({
|
|||
const tabindex = this.props.isFiltered ? "0" : "-1";
|
||||
return (
|
||||
<div className="mx_RoomSubList_labelContainer" title={ title } ref="header">
|
||||
<AccessibleButton onClick={ this.onClick } className="mx_RoomSubList_label" tabIndex={tabindex}>
|
||||
<AccessibleButton onClick={this.onClick} className="mx_RoomSubList_label" tabIndex={tabindex} aria-expanded={!isCollapsed}>
|
||||
{ chevron }
|
||||
<span>{this.props.label}</span>
|
||||
{ incomingCall }
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
/*
|
||||
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
|
||||
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
@ -55,7 +56,7 @@ export default class AccessibleTooltipButton extends React.PureComponent {
|
|||
label={title}
|
||||
/> : <div />;
|
||||
return (
|
||||
<AccessibleButton {...props} onMouseOver={this.onMouseOver} onMouseOut={this.onMouseOut}>
|
||||
<AccessibleButton {...props} onMouseOver={this.onMouseOver} onMouseOut={this.onMouseOut} aria-label={title}>
|
||||
{ tip }
|
||||
</AccessibleButton>
|
||||
);
|
||||
|
|
|
@ -183,7 +183,7 @@ module.exports = createReactClass({
|
|||
|
||||
const GeminiScrollbarWrapper = sdk.getComponent('elements.GeminiScrollbarWrapper');
|
||||
return (
|
||||
<div className="mx_MemberInfo">
|
||||
<div className="mx_MemberInfo" role="tabpanel">
|
||||
<GeminiScrollbarWrapper autoshow={true}>
|
||||
<AccessibleButton className="mx_MemberInfo_cancel" onClick={this._onCancel}>
|
||||
<img src={require("../../../../res/img/cancel.svg")} width="18" height="18" className="mx_filterFlipColor" />
|
||||
|
|
|
@ -222,7 +222,7 @@ export default createReactClass({
|
|||
}
|
||||
|
||||
return (
|
||||
<div className="mx_MemberList">
|
||||
<div className="mx_MemberList" role="tabpanel">
|
||||
{ inviteButton }
|
||||
<GeminiScrollbarWrapper autoshow={true}>
|
||||
{ joined }
|
||||
|
|
|
@ -214,7 +214,7 @@ module.exports = createReactClass({
|
|||
|
||||
const groupRoomName = this.state.groupRoom.displayname;
|
||||
return (
|
||||
<div className="mx_MemberInfo">
|
||||
<div className="mx_MemberInfo" role="tabpanel">
|
||||
<GeminiScrollbarWrapper autoshow={true}>
|
||||
<AccessibleButton className="mx_MemberInfo_cancel" onClick={this._onCancel}>
|
||||
<img src={require("../../../../res/img/cancel.svg")} width="18" height="18" className="mx_filterFlipColor" />
|
||||
|
|
|
@ -153,7 +153,7 @@ export default createReactClass({
|
|||
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
|
||||
const TruncatedList = sdk.getComponent("elements.TruncatedList");
|
||||
return (
|
||||
<div className="mx_GroupRoomList">
|
||||
<div className="mx_GroupRoomList" role="tabpanel">
|
||||
{ inviteButton }
|
||||
<GeminiScrollbarWrapper autoshow={true} className="mx_GroupRoomList_joined mx_GroupRoomList_outerWrapper">
|
||||
<TruncatedList className="mx_GroupRoomList_wrapper" truncateAt={this.state.truncateAt}
|
||||
|
|
|
@ -3,6 +3,7 @@ Copyright 2015, 2016 OpenMarket Ltd
|
|||
Copyright 2017 Vector Creations Ltd
|
||||
Copyright 2017 New Vector Ltd
|
||||
Copyright 2018 New Vector Ltd
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -42,8 +43,8 @@ export default class HeaderButton extends React.Component {
|
|||
});
|
||||
|
||||
return <AccessibleButton
|
||||
aria-label={this.props.title}
|
||||
aria-expanded={this.props.isHighlighted}
|
||||
aria-selected={this.props.isHighlighted}
|
||||
role="tab"
|
||||
title={this.props.title}
|
||||
className={classes}
|
||||
onClick={this.onClick}>
|
||||
|
|
|
@ -91,7 +91,7 @@ export default class HeaderButtons extends React.Component {
|
|||
|
||||
render() {
|
||||
// inline style as this will be swapped around in future commits
|
||||
return <div className="mx_HeaderButtons">
|
||||
return <div className="mx_HeaderButtons" role="tablist">
|
||||
{ this.renderButtons() }
|
||||
</div>;
|
||||
}
|
||||
|
|
|
@ -1124,35 +1124,35 @@ module.exports = createReactClass({
|
|||
}
|
||||
|
||||
return (
|
||||
<div className="mx_MemberInfo">
|
||||
<div className="mx_MemberInfo_name">
|
||||
{ backButton }
|
||||
{ e2eIconElement }
|
||||
<h2>{ memberName }</h2>
|
||||
<div className="mx_MemberInfo" role="tabpanel">
|
||||
<div className="mx_MemberInfo_name">
|
||||
{ backButton }
|
||||
{ e2eIconElement }
|
||||
<h2>{ memberName }</h2>
|
||||
</div>
|
||||
{ avatarElement }
|
||||
<div className="mx_MemberInfo_container">
|
||||
|
||||
<div className="mx_MemberInfo_profile">
|
||||
<div className="mx_MemberInfo_profileField">
|
||||
{ this.props.member.userId }
|
||||
</div>
|
||||
{ roomMemberDetails }
|
||||
</div>
|
||||
{ avatarElement }
|
||||
</div>
|
||||
<AutoHideScrollbar className="mx_MemberInfo_scrollContainer">
|
||||
<div className="mx_MemberInfo_container">
|
||||
{ this._renderUserOptions() }
|
||||
|
||||
<div className="mx_MemberInfo_profile">
|
||||
<div className="mx_MemberInfo_profileField">
|
||||
{ this.props.member.userId }
|
||||
</div>
|
||||
{ roomMemberDetails }
|
||||
</div>
|
||||
{ adminTools }
|
||||
|
||||
{ startChat }
|
||||
|
||||
{ this._renderDevices() }
|
||||
|
||||
{ spinner }
|
||||
</div>
|
||||
<AutoHideScrollbar className="mx_MemberInfo_scrollContainer">
|
||||
<div className="mx_MemberInfo_container">
|
||||
{ this._renderUserOptions() }
|
||||
|
||||
{ adminTools }
|
||||
|
||||
{ startChat }
|
||||
|
||||
{ this._renderDevices() }
|
||||
|
||||
{ spinner }
|
||||
</div>
|
||||
</AutoHideScrollbar>
|
||||
</AutoHideScrollbar>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -475,7 +475,7 @@ module.exports = createReactClass({
|
|||
}
|
||||
|
||||
return (
|
||||
<div className="mx_MemberList">
|
||||
<div className="mx_MemberList" role="tabpanel">
|
||||
{ inviteButton }
|
||||
<AutoHideScrollbar>
|
||||
<div className="mx_MemberList_wrapper">
|
||||
|
|
|
@ -382,14 +382,15 @@ module.exports = createReactClass({
|
|||
/>;
|
||||
}
|
||||
|
||||
// The following labels are written in such a fashion to increase screen reader efficiency (speed).
|
||||
if (notifBadges && mentionBadges && !isInvite) {
|
||||
ariaLabel += " " + _t("It has %(count)s unread messages including mentions.", {
|
||||
ariaLabel += " " + _t("%(count)s unread messages including mentions.", {
|
||||
count: notificationCount,
|
||||
});
|
||||
} else if (notifBadges) {
|
||||
ariaLabel += " " + _t("It has %(count)s unread messages.", { count: notificationCount });
|
||||
ariaLabel += " " + _t("%(count)s unread messages.", { count: notificationCount });
|
||||
} else if (mentionBadges && !isInvite) {
|
||||
ariaLabel += " " + _t("It has unread mentions.");
|
||||
ariaLabel += " " + _t("Unread mentions.");
|
||||
}
|
||||
|
||||
return <AccessibleButton tabIndex="0"
|
||||
|
|
|
@ -409,9 +409,9 @@ export default class Stickerpicker extends React.Component {
|
|||
>
|
||||
</AccessibleButton>;
|
||||
}
|
||||
return <div>
|
||||
return <React.Fragment>
|
||||
{stickersButton}
|
||||
{this.state.showStickers && stickerPicker}
|
||||
</div>;
|
||||
</React.Fragment>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ export default class ThirdPartyMemberInfo extends React.Component {
|
|||
|
||||
// We shamelessly rip off the MemberInfo styles here.
|
||||
return (
|
||||
<div className="mx_MemberInfo">
|
||||
<div className="mx_MemberInfo" role="tabpanel">
|
||||
<div className="mx_MemberInfo_name">
|
||||
<AccessibleButton className="mx_MemberInfo_cancel"
|
||||
onClick={this.onCancel}
|
||||
|
|
|
@ -950,9 +950,9 @@
|
|||
"Securely back up your keys to avoid losing them. <a>Learn more.</a>": "Securely back up your keys to avoid losing them. <a>Learn more.</a>",
|
||||
"Not now": "Not now",
|
||||
"Don't ask me again": "Don't ask me again",
|
||||
"It has %(count)s unread messages including mentions.|other": "It has %(count)s unread messages including mentions.",
|
||||
"It has %(count)s unread messages.|other": "It has %(count)s unread messages.",
|
||||
"It has unread mentions.": "It has unread mentions.",
|
||||
"%(count)s unread messages including mentions.|other": "%(count)s unread messages including mentions.",
|
||||
"%(count)s unread messages.|other": "%(count)s unread messages.",
|
||||
"Unread mentions.": "Unread mentions.",
|
||||
"Add a topic": "Add a topic",
|
||||
"Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.": "Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.",
|
||||
"This room has already been upgraded.": "This room has already been upgraded.",
|
||||
|
|
Loading…
Reference in a new issue