Skip to content

Commit 4fd250d

Browse files
author
Eric Olkowski
committed
Added prop to apply a11y attributes
1 parent 4c9a738 commit 4fd250d

File tree

11 files changed

+37
-11
lines changed

11 files changed

+37
-11
lines changed

packages/react-core/src/components/Menu/Menu.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ export interface MenuProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'r
6363
ouiaId?: number | string;
6464
/** Set the value of data-ouia-safe. Only set to true when the component is in a static state, i.e. no animations are occurring. At all other times, this value must be false. */
6565
ouiaSafe?: boolean;
66+
/** @beta The variant of a non-checkbox menu. Determines whether one or more items can be selected. */
67+
selectVariant?: 'single' | 'multi';
6668
}
6769

6870
export interface MenuState {
@@ -267,6 +269,7 @@ class MenuBase extends React.Component<MenuProps, MenuState> {
267269
innerRef,
268270
isRootMenu,
269271
activeMenu,
272+
selectVariant,
270273
/* eslint-enable @typescript-eslint/no-unused-vars */
271274
...props
272275
} = this.props;
@@ -287,7 +290,8 @@ class MenuBase extends React.Component<MenuProps, MenuState> {
287290
onGetMenuHeight,
288291
flyoutRef: this.state.flyoutRef,
289292
setFlyoutRef: flyoutRef => this.setState({ flyoutRef }),
290-
disableHover: this.state.disableHover
293+
disableHover: this.state.disableHover,
294+
selectVariant
291295
}}
292296
>
293297
{isRootMenu && (

packages/react-core/src/components/Menu/MenuContext.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export const MenuContext = React.createContext<{
1515
flyoutRef?: React.Ref<HTMLLIElement>;
1616
setFlyoutRef?: (ref: React.Ref<HTMLLIElement>) => void;
1717
disableHover?: boolean;
18+
selectVariant?: 'single' | 'multi';
1819
}>({
1920
menuId: null,
2021
parentMenu: null,
@@ -29,7 +30,8 @@ export const MenuContext = React.createContext<{
2930
onGetMenuHeight: () => null,
3031
flyoutRef: null,
3132
setFlyoutRef: () => null,
32-
disableHover: false
33+
disableHover: false,
34+
selectVariant: null
3335
});
3436

3537
export const MenuItemContext = React.createContext<{

packages/react-core/src/components/Menu/MenuItem.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ const MenuItemBase: React.FunctionComponent<MenuItemProps> = ({
114114
onDrillOut,
115115
flyoutRef,
116116
setFlyoutRef,
117-
disableHover
117+
disableHover,
118+
selectVariant
118119
} = React.useContext(MenuContext);
119120
let Component = (to ? 'a' : component) as any;
120121
if (hasCheck && !to) {
@@ -315,7 +316,8 @@ const MenuItemBase: React.FunctionComponent<MenuItemProps> = ({
315316
className={css(styles.menuItem, getIsSelected() && !hasCheck && styles.modifiers.selected, className)}
316317
aria-current={getAriaCurrent()}
317318
{...(!hasCheck && { disabled: isDisabled })}
318-
{...(!hasCheck && !flyoutMenu && { role: 'menuitem' })}
319+
{...(!hasCheck && !flyoutMenu && { role: selectVariant ? 'option' : 'menuitem' })}
320+
{...(!hasCheck && !flyoutMenu && selectVariant && { 'aria-selected': getIsSelected() })}
319321
ref={innerRef}
320322
{...(!hasCheck && {
321323
onClick: (event: any) => {
Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as React from 'react';
22
import styles from '@patternfly/react-styles/css/components/Menu/menu';
33
import { css } from '@patternfly/react-styles';
4+
import { MenuContext } from './MenuContext';
45

56
export interface MenuListProps extends React.HTMLProps<HTMLUListElement> {
67
/** Anything that can be rendered inside of menu list */
@@ -13,9 +14,18 @@ export const MenuList: React.FunctionComponent<MenuListProps> = ({
1314
children = null,
1415
className,
1516
...props
16-
}: MenuListProps) => (
17-
<ul role="menu" className={css(styles.menuList, className)} {...props}>
18-
{children}
19-
</ul>
20-
);
17+
}: MenuListProps) => {
18+
const { selectVariant } = React.useContext(MenuContext);
19+
20+
return (
21+
<ul
22+
role={selectVariant ? 'listbox' : 'menu'}
23+
{...(selectVariant && { 'aria-multiselectable': selectVariant === 'multi' })}
24+
className={css(styles.menuList, className)}
25+
{...props}
26+
>
27+
{children}
28+
</ul>
29+
);
30+
};
2131
MenuList.displayName = 'MenuList';

packages/react-core/src/components/Menu/examples/MenuOptionMultiSelect.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export const MenuOptionMultiSelect: React.FunctionComponent = () => {
1515
};
1616

1717
return (
18-
<Menu onSelect={onSelect} activeItemId={0} selected={selectedItems}>
18+
<Menu selectVariant="multi" onSelect={onSelect} activeItemId={0} selected={selectedItems}>
1919
<MenuContent>
2020
<MenuList>
2121
<MenuItem itemId={0}>Option 1</MenuItem>

packages/react-core/src/components/Menu/examples/MenuOptionSingleSelect.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export const MenuOptionSingleSelect: React.FunctionComponent = () => {
1212
};
1313

1414
return (
15-
<Menu onSelect={onSelect} activeItemId={activeItem} selected={selectedItem}>
15+
<Menu selectVariant="single" onSelect={onSelect} activeItemId={activeItem} selected={selectedItem}>
1616
<MenuContent>
1717
<MenuList>
1818
<MenuItem itemId={0}>Option 1</MenuItem>

packages/react-core/src/next/components/Select/Select.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ export interface SelectProps extends MenuProps, OUIAProps {
2828
innerRef?: React.Ref<HTMLDivElement>;
2929
/** z-index of the select menu */
3030
zIndex?: number;
31+
/** The variant of a non-checkbox select. Determines whether one or more items can be selected. */
32+
selectVariant?: 'single' | 'multi';
3133
}
3234

3335
const SelectBase: React.FunctionComponent<SelectProps & OUIAProps> = ({
@@ -42,6 +44,7 @@ const SelectBase: React.FunctionComponent<SelectProps & OUIAProps> = ({
4244
minWidth,
4345
innerRef,
4446
zIndex = 9999,
47+
selectVariant,
4548
...props
4649
}: SelectProps & OUIAProps) => {
4750
const localMenuRef = React.useRef<HTMLDivElement>();
@@ -91,6 +94,7 @@ const SelectBase: React.FunctionComponent<SelectProps & OUIAProps> = ({
9194

9295
const menu = (
9396
<Menu
97+
selectVariant={selectVariant}
9498
className={css(className)}
9599
ref={menuRef}
96100
onSelect={(event, itemId) => onSelect(event, itemId)}

packages/react-core/src/next/components/Select/examples/SelectBasic.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export const SelectBasic: React.FunctionComponent = () => {
4343
onSelect={onSelect}
4444
onOpenChange={isOpen => setIsOpen(isOpen)}
4545
toggle={toggle}
46+
selectVariant="single"
4647
>
4748
<SelectList>
4849
<SelectOption itemId="Option 1">Option 1</SelectOption>

packages/react-core/src/next/components/Select/examples/SelectGrouped.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export const SelectBasic: React.FunctionComponent = () => {
4343
onSelect={onSelect}
4444
onOpenChange={isOpen => setIsOpen(isOpen)}
4545
toggle={toggle}
46+
selectVariant="single"
4647
>
4748
<SelectGroup label="Group 1">
4849
<SelectList>

packages/react-core/src/next/components/Select/examples/SelectMultiTypeahead.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ export const SelectMultiTypeahead: React.FunctionComponent = () => {
178178
onSelect={(ev, selection) => onSelect(selection as string)}
179179
onOpenChange={() => setIsOpen(false)}
180180
toggle={toggle}
181+
selectVariant="multi"
181182
>
182183
<SelectList>
183184
{selectOptions.map((option, index) => (

0 commit comments

Comments
 (0)