React:如何制作可访问的菜单?

React: How to make an accessible menu?

这是我的 codesandbox link:https://codesandbox.io/s/accessible-menu-ejzte

我有一个菜单,当你点击一个按钮时会弹出。它很实用,但我注意到它与我在网上找到的示例不同。

Menu.tsx 只是 ul 和 children:

    <Container
      role="menu"
      id={id}
      ref={menu_ref}
      is_visible={open}
      onKeyDown={handleKeyPress}
      onClick={(e: React.MouseEvent) => {
        e.stopPropagation();
        onClose();
      }}
      {...rest}
    >
      {children}
    </Container>

MenuItem.tsx 是一个带有按钮的 li

const MenuItem = ({ start_text, onClick }: MenuItemProps) => (
  <Container role="none">
    <ClickableWrapper
      onClick={(e: React.MouseEvent) => onClick && onClick(e)}
      role="menuitem"
    >
      <TextContainer>
        {start_text && <StartText>{start_text}</StartText>}
      </TextContainer>
    </ClickableWrapper>
  </Container>
);

但是,当我查看其他网站时,他们的菜单行为与我的不同:

  1. https://www.w3.org/TR/wai-aria-practices/examples/menu-button/menu-button-links.html
  2. https://mui.com/components/menus/

我注意到了这些差异:

  1. 当您通过切换到按钮并按 Enter
  2. 打开菜单时,第一个菜单项会自动聚焦
  3. 如果菜单处于打开状态并且您按 Esc,则菜单会关闭并且按钮获得焦点

此功能是否来自 Javascript?还是正确构建的菜单的默认行为?

我认为可访问元素都是通过原生 HTML 实现的,但到目前为止我找不到我的 HTML 标记与上面的 2 个示例之间的任何差异,所以这让我认为这只能通过JS实现。

您提供的示例使用的是JS。

w3 示例: 要关闭 Esc,请参阅此文件:

https://www.w3.org/TR/wai-aria-practices/examples/menu-button/js/MenuItemLinks.js 并搜索 'ESC'

为了关注第一个 child,请查看这两个文件并搜索 'setFocusToFirstItem':

https://www.w3.org/TR/wai-aria-practices/examples/menu-button/js/MenuItemLinks.js https://www.w3.org/TR/wai-aria-practices/examples/menu-button/js/PopupMenuLinks.js

MUI例子你可以搜索源码: https://github.com/mui-org/material-ui/blob/master/packages/mui-material/src/MenuList/MenuList.js

您必须更新您的沙盒,因为关闭 Esc 正在运行(通过 JS)。