From f1db0cf027a8dc3c1d3065ae8de40d9beecd50e3 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 3 Oct 2019 09:35:39 +0100 Subject: [PATCH] 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> --- src/components/structures/FilePanel.js | 3 +- .../structures/NotificationPanel.js | 3 +- src/components/structures/RoomSubList.js | 2 +- .../views/elements/AccessibleTooltipButton.js | 25 +++++----- .../views/groups/GroupMemberInfo.js | 2 +- .../views/groups/GroupMemberList.js | 2 +- src/components/views/groups/GroupRoomInfo.js | 2 +- src/components/views/groups/GroupRoomList.js | 2 +- .../views/right_panel/HeaderButton.js | 5 +- .../views/right_panel/HeaderButtons.js | 2 +- src/components/views/rooms/MemberInfo.js | 50 +++++++++---------- src/components/views/rooms/MemberList.js | 2 +- src/components/views/rooms/RoomTile.js | 7 +-- src/components/views/rooms/Stickerpicker.js | 4 +- .../views/rooms/ThirdPartyMemberInfo.js | 2 +- src/i18n/strings/en_EN.json | 6 +-- 16 files changed, 62 insertions(+), 57 deletions(-) diff --git a/src/components/structures/FilePanel.js b/src/components/structures/FilePanel.js index 2b9594581e..fb2bdcad42 100644 --- a/src/components/structures/FilePanel.js +++ b/src/components/structures/FilePanel.js @@ -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 ( -
+
); diff --git a/src/components/structures/NotificationPanel.js b/src/components/structures/NotificationPanel.js index f9ce0e008e..3a07bf2e63 100644 --- a/src/components/structures/NotificationPanel.js +++ b/src/components/structures/NotificationPanel.js @@ -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 ( -
+
); diff --git a/src/components/structures/RoomSubList.js b/src/components/structures/RoomSubList.js index f1057819ff..3d09c05c43 100644 --- a/src/components/structures/RoomSubList.js +++ b/src/components/structures/RoomSubList.js @@ -258,7 +258,7 @@ const RoomSubList = createReactClass({ const tabindex = this.props.isFiltered ? "0" : "-1"; return (
- + { chevron } {this.props.label} { incomingCall } diff --git a/src/components/views/elements/AccessibleTooltipButton.js b/src/components/views/elements/AccessibleTooltipButton.js index c9a08f6a47..c824ea4025 100644 --- a/src/components/views/elements/AccessibleTooltipButton.js +++ b/src/components/views/elements/AccessibleTooltipButton.js @@ -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} /> :
; return ( - + { tip } ); diff --git a/src/components/views/groups/GroupMemberInfo.js b/src/components/views/groups/GroupMemberInfo.js index 75e647aa4b..3dac90fc35 100644 --- a/src/components/views/groups/GroupMemberInfo.js +++ b/src/components/views/groups/GroupMemberInfo.js @@ -183,7 +183,7 @@ module.exports = createReactClass({ const GeminiScrollbarWrapper = sdk.getComponent('elements.GeminiScrollbarWrapper'); return ( -
+
diff --git a/src/components/views/groups/GroupMemberList.js b/src/components/views/groups/GroupMemberList.js index d13f54579d..433625419d 100644 --- a/src/components/views/groups/GroupMemberList.js +++ b/src/components/views/groups/GroupMemberList.js @@ -222,7 +222,7 @@ export default createReactClass({ } return ( -
+
{ inviteButton } { joined } diff --git a/src/components/views/groups/GroupRoomInfo.js b/src/components/views/groups/GroupRoomInfo.js index c6d07cee50..420c163769 100644 --- a/src/components/views/groups/GroupRoomInfo.js +++ b/src/components/views/groups/GroupRoomInfo.js @@ -214,7 +214,7 @@ module.exports = createReactClass({ const groupRoomName = this.state.groupRoom.displayname; return ( -
+
diff --git a/src/components/views/groups/GroupRoomList.js b/src/components/views/groups/GroupRoomList.js index 81921568d0..d57d5e313f 100644 --- a/src/components/views/groups/GroupRoomList.js +++ b/src/components/views/groups/GroupRoomList.js @@ -153,7 +153,7 @@ export default createReactClass({ const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper"); const TruncatedList = sdk.getComponent("elements.TruncatedList"); return ( -
+
{ inviteButton } diff --git a/src/components/views/right_panel/HeaderButtons.js b/src/components/views/right_panel/HeaderButtons.js index 2fa9935ab8..a01b511dc8 100644 --- a/src/components/views/right_panel/HeaderButtons.js +++ b/src/components/views/right_panel/HeaderButtons.js @@ -91,7 +91,7 @@ export default class HeaderButtons extends React.Component { render() { // inline style as this will be swapped around in future commits - return
+ return
{ this.renderButtons() }
; } diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index 1127c53854..2c667b83df 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -1124,35 +1124,35 @@ module.exports = createReactClass({ } return ( -
-
- { backButton } - { e2eIconElement } -

{ memberName }

+
+
+ { backButton } + { e2eIconElement } +

{ memberName }

+
+ { avatarElement } +
+ +
+
+ { this.props.member.userId } +
+ { roomMemberDetails }
- { avatarElement } +
+
+ { this._renderUserOptions() } -
-
- { this.props.member.userId } -
- { roomMemberDetails } -
+ { adminTools } + + { startChat } + + { this._renderDevices() } + + { spinner }
- -
- { this._renderUserOptions() } - - { adminTools } - - { startChat } - - { this._renderDevices() } - - { spinner } -
-
+
); }, diff --git a/src/components/views/rooms/MemberList.js b/src/components/views/rooms/MemberList.js index 1ecb04d442..0805c0342c 100644 --- a/src/components/views/rooms/MemberList.js +++ b/src/components/views/rooms/MemberList.js @@ -475,7 +475,7 @@ module.exports = createReactClass({ } return ( -
+
{ inviteButton }
diff --git a/src/components/views/rooms/RoomTile.js b/src/components/views/rooms/RoomTile.js index a7ba744e47..f2512e06c2 100644 --- a/src/components/views/rooms/RoomTile.js +++ b/src/components/views/rooms/RoomTile.js @@ -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 ; } - return
+ return {stickersButton} {this.state.showStickers && stickerPicker} -
; + ; } } diff --git a/src/components/views/rooms/ThirdPartyMemberInfo.js b/src/components/views/rooms/ThirdPartyMemberInfo.js index 754e32871f..db6ab479a3 100644 --- a/src/components/views/rooms/ThirdPartyMemberInfo.js +++ b/src/components/views/rooms/ThirdPartyMemberInfo.js @@ -121,7 +121,7 @@ export default class ThirdPartyMemberInfo extends React.Component { // We shamelessly rip off the MemberInfo styles here. return ( -
+
Learn more.": "Securely back up your keys to avoid losing them. Learn more.", "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.",