Accessibility
The Popover component has been designed with accessibility in mind, providing features that enhance the experience for users of assistive technologies.
Accessibility props
The following props are available to improve the accessibility of your Popover component:
Prop | Type | Default | Description |
---|---|---|---|
ariaLabel | string | Adds aria-label to the popover content, providing a description for screen readers. | |
ariaLabelledby | string | References the ID of an element that labels the popover content for screen readers. | |
role | "dialog" \| "menu" \| "grid" \| "listbox" \| "tree" | "dialog" | Defines the ARIA role of the popover component. |
labelClose | React.Node | "Close" | The label for the close button displayed on mobile devices. |
Automatic Accessibility Features
The Popover component automatically handles several important ARIA attributes on the trigger element:
aria-controls
: Links the trigger element to the popover content using a unique ID orid
provided via props.aria-haspopup
: Indicates that the trigger reveals additional content (set to the popover’s role).aria-expanded
: Indicates whether the popover is currently visible or hidden.
These attributes are managed by the component and do not need to be manually added to your code.
Best practices
Non-interactive trigger elements
The Popover’s trigger element (provided as children
) should not be an interactive element like a native <button>
or <a>
tag, as this creates nested interactive elements which is an accessibility violation.
For example, if using a Button component as a trigger, set asComponent="div"
to avoid this issue:
<Popover content="Popover content"><Button asComponent="div">Open popover</Button></Popover>
Descriptive labels
- Provide meaningful
ariaLabel
orariaLabelledby
props to help screen reader users understand the purpose of the popover. - The
ariaLabel
should be concise but descriptive, such as “Passenger selection” or “Filter options”. - When using
ariaLabelledby
, ensure the referenced element (by ID) contains clear, descriptive text that explains the popover’s purpose. - Always ensure that
ariaLabel
text and any text in elements referenced byariaLabelledby
are properly translated to match the user’s language.
For example:
// Using ariaLabel<Popover ariaLabel="Passenger selection options" content={passengerSelectionContent}><Button asComponent="div">Select passengers</Button></Popover>
// Using ariaLabelledby<div><h2 id="passenger-selection-heading">Passenger selection</h2><Popover ariaLabelledby="passenger-selection-heading" content={passengerSelectionContent}><Button asComponent="div">Select passengers</Button></Popover></div>
The ariaLabel
and ariaLabelledby
props provide important context about the popover’s content to screen reader users. Always use one of these props to ensure your Popover is accessible.
Custom close label
When the popover is closable on mobile devices, the default “Close” label can be overridden with a more descriptive one using the labelClose
prop.
<Popover content="Popover content" labelClose="Close passenger selection"><Button asComponent="div">Select passengers</Button></Popover>
Keyboard navigation
The Popover component supports keyboard navigation:
- The popover can be opened by pressing Enter or Space when the trigger element has focus.
- When open, the popover can be closed by pressing Escape.
- Focus is properly managed within the popover when it’s open.
Appropriate roles
The role
prop should be chosen based on the popover’s content and purpose:
- Use
"dialog"
(the default) for most cases, especially when presenting forms or information. - Use
"menu"
when the popover contains a list of actions or menu items. - Use
"listbox"
when presenting a list of selectable options. - Use
"grid"
for tabular data. - Use
"tree"
for hierarchical, expandable/collapsible content.
Examples
Basic popover with proper labeling
<Popovercontent={<Text>This is additional information about this feature.</Text>}ariaLabel="Feature information"><Button asComponent="div">More info</Button></Popover>
Screen readers would announce: “More info, dialogue pop-up collapsed, button” and when opened: “Feature information, dialog”.
Popover with custom role and existing label
<Stack><h2 id="passenger-selection">Passenger selection</h2><Popovercontent={<Stack><StepperminValue={0}ariaLabelValue="Number of adult passengers"titleIncrement="Add adult passenger"titleDecrement="Remove adult passenger"/></Stack>}role="menu"ariaLabelledby="passenger-selection"><Button asComponent="div" iconRight={<ChevronDown />}>Select passengers</Button></Popover></Stack>
In this example, screen readers would announce “Select passengers, menu pop-up collapsed, button” and when opened: “Passenger selection, menu”.