From b7ed41cb0b3c8a868a3b48ec4dd09da1f57be0e1 Mon Sep 17 00:00:00 2001 From: Dylan Kilgore Date: Fri, 31 Mar 2023 17:25:05 -0700 Subject: [PATCH] fix: menu: fixes keyboard focus and screen reader functionality --- src/components/Dropdown/Dropdown.stories.tsx | 2 + src/components/Dropdown/Dropdown.tsx | 38 ++++++++++++------- src/components/Dropdown/Dropdown.types.ts | 5 +++ src/components/Link/Link.tsx | 3 +- src/components/Link/Link.types.ts | 4 ++ src/components/List/List.tsx | 2 - .../MenuItemButton/MenuItemButton.tsx | 9 ++--- .../MenuItem/MenuItemLink/MenuItemLink.tsx | 3 +- .../Menu/__snapshots__/Menu.test.tsx.snap | 33 ++++++---------- 9 files changed, 55 insertions(+), 44 deletions(-) diff --git a/src/components/Dropdown/Dropdown.stories.tsx b/src/components/Dropdown/Dropdown.stories.tsx index b70cb3f42..11f8ea62b 100644 --- a/src/components/Dropdown/Dropdown.stories.tsx +++ b/src/components/Dropdown/Dropdown.stories.tsx @@ -121,11 +121,13 @@ const Overlay = () => ( iconProps={{ path: item.icon, }} + role="menuitem" style={{ margin: '4px 0', }} /> )} + role="menu" /> ); diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx index 6f3e2c2a3..fd73a45db 100644 --- a/src/components/Dropdown/Dropdown.tsx +++ b/src/components/Dropdown/Dropdown.tsx @@ -9,6 +9,7 @@ import React, { import { autoUpdate, flip, + FloatingFocusManager, FloatingPortal, offset as fOffset, shift, @@ -62,6 +63,7 @@ export const Dropdown: FC = React.memo( placement = 'bottom-start', portal = false, positionStrategy = 'absolute', + role = 'listbox', showDropdown, style, trigger = 'click', @@ -78,13 +80,12 @@ export const Dropdown: FC = React.memo( const dropdownId: string = uniqueId('dropdown-'); let timeout: ReturnType; - const { x, y, reference, floating, strategy, update, refs } = useFloating( - { + const { x, y, reference, floating, strategy, update, refs, context } = + useFloating({ placement, strategy: positionStrategy, middleware: [fOffset(offset), flip(), shift()], - } - ); + }); const toggle: Function = (show: boolean, showDropdown = (show: boolean) => show): Function => @@ -191,16 +192,27 @@ export const Dropdown: FC = React.memo( const getDropdown = (): JSX.Element => mergedVisible && ( -
- {overlay} -
+
+ {overlay} +
+ ); return ( diff --git a/src/components/Dropdown/Dropdown.types.ts b/src/components/Dropdown/Dropdown.types.ts index b70179aba..dfa54b7ab 100644 --- a/src/components/Dropdown/Dropdown.types.ts +++ b/src/components/Dropdown/Dropdown.types.ts @@ -66,6 +66,11 @@ export interface DropdownProps { * @default absolute */ positionStrategy?: Strategy; + /** + * The dropdown aria role. + * @default 'listbox' + */ + role?: string; /** * Callback to control the show/hide behavior of the dropdown. * triggered before the visible change diff --git a/src/components/Link/Link.tsx b/src/components/Link/Link.tsx index 81d71ed36..440f84b1a 100644 --- a/src/components/Link/Link.tsx +++ b/src/components/Link/Link.tsx @@ -14,6 +14,7 @@ export const Link: FC = React.forwardRef( disabled = false, fullWidth = true, onClick, + role = 'link', target = '_self', underline, variant = 'default', @@ -49,7 +50,7 @@ export const Link: FC = React.forwardRef( ; + /** + * The Link role. + */ + role?: string; /** * Whether to show the Link underline. */ diff --git a/src/components/List/List.tsx b/src/components/List/List.tsx index 4d568a2e8..41bacc595 100644 --- a/src/components/List/List.tsx +++ b/src/components/List/List.tsx @@ -15,7 +15,6 @@ export const List = ({ header, classNames, style, - tabIndex = 0, itemClassNames, itemStyle, listType = 'ul', @@ -61,7 +60,6 @@ export const List = ({ key={getItemKey(item, index)} className={itemClasses} style={itemStyle} - tabIndex={tabIndex} > {renderItem(item)} diff --git a/src/components/Menu/MenuItem/MenuItemButton/MenuItemButton.tsx b/src/components/Menu/MenuItem/MenuItemButton/MenuItemButton.tsx index ece93c951..dfa60d32b 100644 --- a/src/components/Menu/MenuItem/MenuItemButton/MenuItemButton.tsx +++ b/src/components/Menu/MenuItem/MenuItemButton/MenuItemButton.tsx @@ -87,6 +87,7 @@ export const MenuItemButton: FC = ({ tabIndex={tabIndex} {...rest} onClick={handleOnClick} + role={role} > {iconProps && alignIcon === MenuItemIconAlign.Left && getIcon()} @@ -102,7 +103,7 @@ export const MenuItemButton: FC = ({ const secondaryButton = (): JSX.Element => ( <> - +