Skip to content

Commit

Permalink
fix: menu: fixes keyboard focus and screen reader functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
dkilgore-eightfold committed Apr 1, 2023
1 parent c4dc4aa commit b7ed41c
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 44 deletions.
2 changes: 2 additions & 0 deletions src/components/Dropdown/Dropdown.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,13 @@ const Overlay = () => (
iconProps={{
path: item.icon,
}}
role="menuitem"
style={{
margin: '4px 0',
}}
/>
)}
role="menu"
/>
);

Expand Down
38 changes: 25 additions & 13 deletions src/components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import React, {
import {
autoUpdate,
flip,
FloatingFocusManager,
FloatingPortal,
offset as fOffset,
shift,
Expand Down Expand Up @@ -62,6 +63,7 @@ export const Dropdown: FC<DropdownProps> = React.memo(
placement = 'bottom-start',
portal = false,
positionStrategy = 'absolute',
role = 'listbox',
showDropdown,
style,
trigger = 'click',
Expand All @@ -78,13 +80,12 @@ export const Dropdown: FC<DropdownProps> = React.memo(
const dropdownId: string = uniqueId('dropdown-');

let timeout: ReturnType<typeof setTimeout>;
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 =>
Expand Down Expand Up @@ -191,16 +192,27 @@ export const Dropdown: FC<DropdownProps> = React.memo(

const getDropdown = (): JSX.Element =>
mergedVisible && (
<div
ref={floating}
style={dropdownStyles}
className={dropdownClasses}
tabIndex={0}
onClick={closeOnDropdownClick ? toggle(false, showDropdown) : null}
id={dropdownId}
<FloatingFocusManager
context={context}
key={dropdownId}
modal={false}
order={['reference', 'content']}
returnFocus={false}
>
{overlay}
</div>
<div
ref={floating}
style={dropdownStyles}
className={dropdownClasses}
role={role}
tabIndex={0}
onClick={
closeOnDropdownClick ? toggle(false, showDropdown) : null
}
id={dropdownId}
>
{overlay}
</div>
</FloatingFocusManager>
);

return (
Expand Down
5 changes: 5 additions & 0 deletions src/components/Dropdown/Dropdown.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion src/components/Link/Link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const Link: FC<LinkProps> = React.forwardRef(
disabled = false,
fullWidth = true,
onClick,
role = 'link',
target = '_self',
underline,
variant = 'default',
Expand Down Expand Up @@ -49,7 +50,7 @@ export const Link: FC<LinkProps> = React.forwardRef(
<a
{...rest}
ref={ref}
role="link"
role={role}
aria-disabled={disabled}
className={linkClassNames}
href={href}
Expand Down
4 changes: 4 additions & 0 deletions src/components/Link/Link.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ export interface LinkProps
* The Link onClick event handler.
*/
onClick?: React.MouseEventHandler<HTMLAnchorElement>;
/**
* The Link role.
*/
role?: string;
/**
* Whether to show the Link underline.
*/
Expand Down
2 changes: 0 additions & 2 deletions src/components/List/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export const List = <T extends any>({
header,
classNames,
style,
tabIndex = 0,
itemClassNames,
itemStyle,
listType = 'ul',
Expand Down Expand Up @@ -61,7 +60,6 @@ export const List = <T extends any>({
key={getItemKey(item, index)}
className={itemClasses}
style={itemStyle}
tabIndex={tabIndex}
>
{renderItem(item)}
</li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export const MenuItemButton: FC<MenuItemButtonProps> = ({
tabIndex={tabIndex}
{...rest}
onClick={handleOnClick}
role={role}
>
{iconProps && alignIcon === MenuItemIconAlign.Left && getIcon()}
<span className={styles.menuItemWrapper}>
Expand All @@ -102,7 +103,7 @@ export const MenuItemButton: FC<MenuItemButtonProps> = ({

const secondaryButton = (): JSX.Element => (
<>
<span className={styles.menuSecondaryWrapper}>
<span className={styles.menuSecondaryWrapper} role={role}>
<button
className={styles.menuOuterButton}
disabled={disabled}
Expand Down Expand Up @@ -153,9 +154,5 @@ export const MenuItemButton: FC<MenuItemButtonProps> = ({
return dropdownMenuItems ? dropdownMenuButton() : menuButton();
};

return (
<li role={role} tabIndex={-1} className={menuItemClassNames}>
{renderedItem()}
</li>
);
return <li className={menuItemClassNames}>{renderedItem()}</li>;
};
3 changes: 2 additions & 1 deletion src/components/Menu/MenuItem/MenuItemLink/MenuItemLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,12 @@ export const MenuItemLink: FC<MenuItemLinkProps> = ({
);

return (
<li role={role} tabIndex={-1} className={menuItemClassNames}>
<li className={menuItemClassNames}>
<Link
classNames={styles.menuLink}
disabled={disabled}
fullWidth
role={role}
tabIndex={tabIndex}
{...rest}
>
Expand Down
33 changes: 12 additions & 21 deletions src/components/Menu/__snapshots__/Menu.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ exports[`Menu Menu is large 1`] = `
<div
class="dropdown-wrapper no-padding open"
id="dropdown-"
role="listbox"
style="position: absolute; top: 4px; left: 0px;"
tabindex="0"
>
Expand All @@ -36,11 +37,10 @@ exports[`Menu Menu is large 1`] = `
>
<li
class="menu-item large neutral my-menu-item-class"
role="menuitem"
tabindex="-1"
>
<button
class="menu-item-button"
role="menuitem"
tabindex="0"
>
<span
Expand Down Expand Up @@ -79,12 +79,11 @@ exports[`Menu Menu is large 1`] = `
</li>
<li
class="menu-item large neutral disabled my-menu-item-class"
role="menuitem"
tabindex="-1"
>
<button
class="menu-item-button"
disabled=""
role="menuitem"
tabindex="0"
>
<span
Expand All @@ -109,14 +108,12 @@ exports[`Menu Menu is large 1`] = `
</span>
<li
class="menu-item large neutral my-menu-item-class"
role="menuitem"
tabindex="-1"
>
<a
aria-disabled="false"
class="link-style full-width menu-link"
href="https://twitter.com"
role="link"
role="menuitem"
tabindex="0"
target="_blank"
>
Expand Down Expand Up @@ -254,6 +251,7 @@ exports[`Menu Menu is medium 1`] = `
<div
class="dropdown-wrapper no-padding open"
id="dropdown-"
role="listbox"
style="position: absolute; top: 4px; left: 0px;"
tabindex="0"
>
Expand All @@ -267,11 +265,10 @@ exports[`Menu Menu is medium 1`] = `
>
<li
class="menu-item medium neutral my-menu-item-class"
role="menuitem"
tabindex="-1"
>
<button
class="menu-item-button"
role="menuitem"
tabindex="0"
>
<span
Expand Down Expand Up @@ -310,12 +307,11 @@ exports[`Menu Menu is medium 1`] = `
</li>
<li
class="menu-item medium neutral disabled my-menu-item-class"
role="menuitem"
tabindex="-1"
>
<button
class="menu-item-button"
disabled=""
role="menuitem"
tabindex="0"
>
<span
Expand All @@ -340,14 +336,12 @@ exports[`Menu Menu is medium 1`] = `
</span>
<li
class="menu-item medium neutral my-menu-item-class"
role="menuitem"
tabindex="-1"
>
<a
aria-disabled="false"
class="link-style full-width menu-link"
href="https://twitter.com"
role="link"
role="menuitem"
tabindex="0"
target="_blank"
>
Expand Down Expand Up @@ -485,6 +479,7 @@ exports[`Menu Menu is small 1`] = `
<div
class="dropdown-wrapper no-padding open"
id="dropdown-"
role="listbox"
style="position: absolute; top: 4px; left: 0px;"
tabindex="0"
>
Expand All @@ -498,11 +493,10 @@ exports[`Menu Menu is small 1`] = `
>
<li
class="menu-item small neutral my-menu-item-class"
role="menuitem"
tabindex="-1"
>
<button
class="menu-item-button"
role="menuitem"
tabindex="0"
>
<span
Expand Down Expand Up @@ -541,12 +535,11 @@ exports[`Menu Menu is small 1`] = `
</li>
<li
class="menu-item small neutral disabled my-menu-item-class"
role="menuitem"
tabindex="-1"
>
<button
class="menu-item-button"
disabled=""
role="menuitem"
tabindex="0"
>
<span
Expand All @@ -571,14 +564,12 @@ exports[`Menu Menu is small 1`] = `
</span>
<li
class="menu-item small neutral my-menu-item-class"
role="menuitem"
tabindex="-1"
>
<a
aria-disabled="false"
class="link-style full-width menu-link"
href="https://twitter.com"
role="link"
role="menuitem"
tabindex="0"
target="_blank"
>
Expand Down

0 comments on commit b7ed41c

Please sign in to comment.