Improve keyboard accessibility using :focus-visible CSS polyfill

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski 2019-09-27 09:00:54 +01:00
parent 3674b87415
commit 8d1d3090f3
6 changed files with 40 additions and 17 deletions

View file

@ -75,6 +75,7 @@
"filesize": "3.5.6",
"flux": "2.1.1",
"focus-trap-react": "^3.0.5",
"focus-visible": "^5.0.2",
"fuse.js": "^2.2.0",
"gemini-scrollbar": "github:matrix-org/gemini-scrollbar#91e1e566",
"gfm.css": "^1.1.1",

View file

@ -18,7 +18,7 @@ limitations under the License.
cursor: pointer;
}
.mx_AccessibleButton:focus {
.mx_AccessibleButton:focus:not(.focus-visible) {
outline: 0;
}

View file

@ -41,7 +41,9 @@ import * as Rooms from '../../Rooms';
import linkifyMatrix from "../../linkify-matrix";
import * as Lifecycle from '../../Lifecycle';
// LifecycleStore is not used but does listen to and dispatch actions
require('../../stores/LifecycleStore');
import '../../stores/LifecycleStore';
// focus-visible is a Polyfill for the :focus-visible CSS pseudo-attribute used by _AccessibleButton.scss
import 'focus-visible';
import PageTypes from '../../PageTypes';
import { getHomePageUrl } from '../../utils/pages';

View file

@ -24,6 +24,7 @@ import Modal from "../../../Modal";
import SdkConfig from '../../../SdkConfig';
import { getHostingLink } from '../../../utils/HostingLink';
import MatrixClientPeg from '../../../MatrixClientPeg';
import sdk from "../../../index";
export class TopLeftMenu extends React.Component {
static propTypes = {
@ -57,6 +58,8 @@ export class TopLeftMenu extends React.Component {
}
render() {
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
const isGuest = MatrixClientPeg.get().isGuest();
const hostingSignupLink = getHostingLink('user-context-menu');
@ -77,25 +80,33 @@ export class TopLeftMenu extends React.Component {
let homePageItem = null;
if (this.hasHomePage()) {
homePageItem = <li className="mx_TopLeftMenu_icon_home" onClick={this.viewHomePage} tabIndex={0}>
{_t("Home")}
</li>;
homePageItem = (
<AccessibleButton element="li" className="mx_TopLeftMenu_icon_home" onClick={this.viewHomePage}>
{_t("Home")}
</AccessibleButton>
);
}
let signInOutItem;
if (isGuest) {
signInOutItem = <li className="mx_TopLeftMenu_icon_signin" onClick={this.signIn} tabIndex={0}>
{_t("Sign in")}
</li>;
signInOutItem = (
<AccessibleButton element="li" className="mx_TopLeftMenu_icon_signin" onClick={this.signIn}>
{_t("Sign in")}
</AccessibleButton>
);
} else {
signInOutItem = <li className="mx_TopLeftMenu_icon_signout" onClick={this.signOut} tabIndex={0}>
{_t("Sign out")}
</li>;
signInOutItem = (
<AccessibleButton element="li" className="mx_TopLeftMenu_icon_signout" onClick={this.signOut}>
{_t("Sign out")}
</AccessibleButton>
);
}
const settingsItem = <li className="mx_TopLeftMenu_icon_settings" onClick={this.openSettings} tabIndex={0}>
{_t("Settings")}
</li>;
const settingsItem = (
<AccessibleButton element="li" className="mx_TopLeftMenu_icon_settings" onClick={this.openSettings}>
{_t("Settings")}
</AccessibleButton>
);
return <div className="mx_TopLeftMenu mx_HiddenFocusable" tabIndex={0} ref={this.props.containerRef}>
<div className="mx_TopLeftMenu_section_noIcon" aria-readonly={true}>

View file

@ -140,6 +140,8 @@ export default class MessageActionBar extends React.PureComponent {
}
render() {
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
let reactButton;
let replyButton;
let editButton;
@ -149,14 +151,16 @@ export default class MessageActionBar extends React.PureComponent {
reactButton = this.renderReactButton();
}
if (this.context.room.canReply) {
replyButton = <span className="mx_MessageActionBar_maskButton mx_MessageActionBar_replyButton"
replyButton = <AccessibleButton
className="mx_MessageActionBar_maskButton mx_MessageActionBar_replyButton"
title={_t("Reply")}
onClick={this.onReplyClick}
/>;
}
}
if (canEditContent(this.props.mxEvent)) {
editButton = <span className="mx_MessageActionBar_maskButton mx_MessageActionBar_editButton"
editButton = <AccessibleButton
className="mx_MessageActionBar_maskButton mx_MessageActionBar_editButton"
title={_t("Edit")}
onClick={this.onEditClick}
/>;
@ -166,7 +170,7 @@ export default class MessageActionBar extends React.PureComponent {
{reactButton}
{replyButton}
{editButton}
<span
<AccessibleButton
className="mx_MessageActionBar_maskButton mx_MessageActionBar_optionsButton"
title={_t("Options")}
onClick={this.onOptionsClick}

View file

@ -3367,6 +3367,11 @@ focus-trap@^2.0.1:
dependencies:
tabbable "^1.0.3"
focus-visible@^5.0.2:
version "5.0.2"
resolved "https://registry.yarnpkg.com/focus-visible/-/focus-visible-5.0.2.tgz#4fae9cf40458b73c10701c9774c462e3ccd53caf"
integrity sha512-zT2fj/bmOgEBjqGbURGlowTmCwsIs3bRDMr/sFZz8Ly7VkEiwuCn9swNTL3pPuf8Oua2de7CLuKdnuNajWdDsQ==
follow-redirects@^1.0.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.7.0.tgz#489ebc198dc0e7f64167bd23b03c4c19b5784c76"