Improve keyboard accessibility using :focus-visible CSS polyfill
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
3674b87415
commit
8d1d3090f3
6 changed files with 40 additions and 17 deletions
|
@ -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",
|
||||
|
|
|
@ -18,7 +18,7 @@ limitations under the License.
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_AccessibleButton:focus {
|
||||
.mx_AccessibleButton:focus:not(.focus-visible) {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -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}>
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in a new issue