From 2a187810fd66d7d45bcccf0f8fb64691fd0578c6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 17 May 2019 15:32:03 -0600 Subject: [PATCH] Restructure TopLeftMenu for accessibility and autofocus it We use a trick with refs to automatically focus the element, also making use of mx_HiddenFocusable to hide the unnecessary outline. The menu itself has been restructured to hide some elements from screen readers (reduce noise) and to have a single unordered list. Screen readers mention when the user "enters" a list, and each item was previously saying "enter list " when it should have just been "". By focusing automatically, the keyboard can be used to go up/down the menu as may be expected by keyboard users. --- .../views/context_menus/TopLeftMenu.js | 43 +++++++++++-------- src/utils/Accessibility.js | 19 ++++++++ 2 files changed, 43 insertions(+), 19 deletions(-) create mode 100644 src/utils/Accessibility.js diff --git a/src/components/views/context_menus/TopLeftMenu.js b/src/components/views/context_menus/TopLeftMenu.js index 278c879404..14e93044f4 100644 --- a/src/components/views/context_menus/TopLeftMenu.js +++ b/src/components/views/context_menus/TopLeftMenu.js @@ -23,6 +23,7 @@ import Modal from "../../../Modal"; import SdkConfig from '../../../SdkConfig'; import { getHostingLink } from '../../../utils/HostingLink'; import MatrixClientPeg from '../../../MatrixClientPeg'; +import {focusCapturedRef} from "../../../utils/Accessibility"; export class TopLeftMenu extends React.Component { static propTypes = { @@ -61,44 +62,48 @@ export class TopLeftMenu extends React.Component { {_t( "Upgrade to your own domain", {}, { - a: sub => {sub}, + a: sub => {sub}, }, )} - + ; } - let homePageSection = null; + let homePageItem = null; if (this.hasHomePage()) { - homePageSection =
    -
  • {_t("Home")}
  • -
; + homePageItem =
  • + {_t("Home")} +
  • ; } - let signInOutSection; + let signInOutItem; if (isGuest) { - signInOutSection =
      -
    • {_t("Sign in")}
    • -
    ; + signInOutItem =
  • + {_t("Sign in")} +
  • ; } else { - signInOutSection =
      -
    • {_t("Sign out")}
    • -
    ; + signInOutItem =
  • + {_t("Sign out")} +
  • ; } - return
    -
    + const settingsItem =
  • + {_t("Settings")} +
  • ; + + return
    +
    {this.props.displayName}
    -
    {this.props.userId}
    +
    {this.props.userId}
    {hostingSignup}
    - {homePageSection}
      -
    • {_t("Settings")}
    • + {homePageItem} + {settingsItem} + {signInOutItem}
    - {signInOutSection}
    ; } diff --git a/src/utils/Accessibility.js b/src/utils/Accessibility.js new file mode 100644 index 0000000000..dbdfeec7df --- /dev/null +++ b/src/utils/Accessibility.js @@ -0,0 +1,19 @@ +/* +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 + + 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. +*/ + +export function focusCapturedRef(ref) { + if (ref) ref.focus(); +} \ No newline at end of file