From 14e3cb87361de82e784f95ad154921225e39a849 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 26 Sep 2019 13:52:09 +0100 Subject: [PATCH 1/7] Allow keyboard control even without a screen reader Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/TabbedView.js | 10 ++++++++ src/components/views/elements/ToggleSwitch.js | 23 +++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/components/structures/TabbedView.js b/src/components/structures/TabbedView.js index 6ececbb329..cf603a75b3 100644 --- a/src/components/structures/TabbedView.js +++ b/src/components/structures/TabbedView.js @@ -1,6 +1,7 @@ /* Copyright 2017 Travis Ralston Copyright 2019 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. @@ -17,6 +18,7 @@ limitations under the License. import * as React from "react"; import {_t} from '../../languageHandler'; +import {KeyCode} from "../../Keyboard"; import PropTypes from "prop-types"; /** @@ -81,6 +83,13 @@ export class TabbedView extends React.Component { } const onClickHandler = () => this._setActiveTab(tab); + const onKeyDownHandler = (e) => { + e.stopPropagation(); + e.preventDefault(); + if (e.keyCode === KeyCode.ENTER || e.keyCode === KeyCode.SPACE) { + this._setActiveTab(tab); + } + }; const label = _t(tab.label); return ( @@ -88,6 +97,7 @@ export class TabbedView extends React.Component { className={classes} key={"tab_label_" + tab.label} onClick={onClickHandler} + onKeyDown={onKeyDownHandler} role="button" aria-label={label} tabIndex={0} diff --git a/src/components/views/elements/ToggleSwitch.js b/src/components/views/elements/ToggleSwitch.js index e8e870edd8..05986e4e99 100644 --- a/src/components/views/elements/ToggleSwitch.js +++ b/src/components/views/elements/ToggleSwitch.js @@ -17,6 +17,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import classNames from "classnames"; +import {KeyCode} from "../../../Keyboard"; export default class ToggleSwitch extends React.Component { static propTypes = { @@ -44,10 +45,7 @@ export default class ToggleSwitch extends React.Component { } } - _onClick = (e) => { - e.stopPropagation(); - e.preventDefault(); - + _toggle = () => { if (this.props.disabled) return; const newState = !this.state.checked; @@ -57,6 +55,22 @@ export default class ToggleSwitch extends React.Component { } }; + _onClick = (e) => { + e.stopPropagation(); + e.preventDefault(); + + this._toggle(); + }; + + _onKeyDown = (e) => { + e.stopPropagation(); + e.preventDefault(); + + if (e.keyCode === KeyCode.ENTER || e.keyCode === KeyCode.SPACE) { + this._toggle(); + } + }; + render() { // eslint-disable-next-line no-unused-vars const {checked, disabled, onChange, ...props} = this.props; @@ -71,6 +85,7 @@ export default class ToggleSwitch extends React.Component { {...props} className={classes} onClick={this._onClick} + onKeyDown={this._onKeyDown} role="checkbox" aria-checked={this.state.checked} aria-disabled={disabled} From 8ec0ffea3a5dac008e491617577f5905625ffeca Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 26 Sep 2019 14:24:10 +0100 Subject: [PATCH 2/7] Make the message context menu more accessible Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/TabbedView.js | 4 +- .../views/context_menus/MessageContextMenu.js | 102 +++++++++++------- .../views/messages/MessageActionBar.js | 4 +- 3 files changed, 69 insertions(+), 41 deletions(-) diff --git a/src/components/structures/TabbedView.js b/src/components/structures/TabbedView.js index cf603a75b3..0e76143f92 100644 --- a/src/components/structures/TabbedView.js +++ b/src/components/structures/TabbedView.js @@ -84,9 +84,9 @@ export class TabbedView extends React.Component { const onClickHandler = () => this._setActiveTab(tab); const onKeyDownHandler = (e) => { - e.stopPropagation(); - e.preventDefault(); if (e.keyCode === KeyCode.ENTER || e.keyCode === KeyCode.SPACE) { + e.stopPropagation(); + e.preventDefault(); this._setActiveTab(tab); } }; diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js index 66005eb730..1d859da047 100644 --- a/src/components/views/context_menus/MessageContextMenu.js +++ b/src/components/views/context_menus/MessageContextMenu.js @@ -2,6 +2,7 @@ Copyright 2015, 2016 OpenMarket Ltd Copyright 2018 New Vector Ltd 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. @@ -30,11 +31,28 @@ import Resend from '../../../Resend'; import SettingsStore from '../../../settings/SettingsStore'; import { isUrlPermitted } from '../../../HtmlUtils'; import { isContentActionable } from '../../../utils/EventUtils'; +import {KeyCode} from "../../../Keyboard"; function canCancel(eventStatus) { return eventStatus === EventStatus.QUEUED || eventStatus === EventStatus.NOT_SENT; } +const DropdownButton = ({children, onClick}) => { + const onKeyDown = (e) => { + if (e.keyCode === KeyCode.ENTER || e.keyCode === KeyCode.SPACE) { + e.stopPropagation(); + e.preventDefault(); + onClick(); + } + }; + return ( +