Skip to content

feat(MenuToggle): add aria-haspopup prop - #12549

Open
Axel-DaMage wants to merge 4 commits into
patternfly:mainfrom
Axel-DaMage:feat/menu-toggle-aria
Open

feat(MenuToggle): add aria-haspopup prop#12549
Axel-DaMage wants to merge 4 commits into
patternfly:mainfrom
Axel-DaMage:feat/menu-toggle-aria

Conversation

@Axel-DaMage

@Axel-DaMage Axel-DaMage commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Fixes #11792
Jira Issue: PF-1704

Description

As a followup to patternfly/patternfly#6561, this PR introduces the aria-haspopup prop to the MenuToggle component to improve screen reader accessibility.

Changes included:

  • Added the aria-haspopup prop to MenuToggleProps with a default value of "menu".
  • Passed the aria-haspopup attribute to the underlying <button> elements in MenuToggleBase.
  • Updated all Select component examples and demos to explicitly pass aria-haspopup="listbox", as Select inherently behaves as a listbox rather than a standard navigation menu.
  • Updated examples in Toolbar, Form, LoginPage, and Tooltip that utilize Select as a filter/dropdown to also explicitly pass aria-haspopup="listbox".
  • Maintained the default "menu" behavior for components that naturally function as menus (e.g., Dropdown, ActionList, DataList kebab actions, etc.).
  • Updated MenuToggle unit test snapshots to reflect the new default attribute.

Visuals

N/A - This is purely an accessibility (A11y) structural change, no visual regressions or changes are introduced.

Summary by CodeRabbit

  • New Features

    • Added configurable popup accessibility semantics to toggle controls, ensuring dropdown-style Select/typeahead interactions expose the correct listbox role.
  • Bug Fixes

    • Updated Login, Select, Toolbar, and Tooltip examples so toggle buttons consistently announce the intended popup behavior to assistive technologies.
    • Refreshed MenuToggle examples to explicitly set aria-haspopup across variants, including cases where no popup is opened.

Adds the aria-haspopup prop to MenuToggle with a default value of 'menu'. Updates all Select implementations across examples and demos to explicitly pass aria-haspopup="listbox" to properly reflect their semantic role, addressing issue patternfly#11792 (PF-1704).
Copilot AI review requested due to automatic review settings July 9, 2026 17:59

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2b102f70-98be-4e81-bf33-0b5e3d2ab2e3

📥 Commits

Reviewing files that changed from the base of the PR and between 36b65d4 and a6cf718.

⛔ Files ignored due to path filters (6)
  • packages/react-table/src/deprecated/components/Table/__tests__/__snapshots__/Table.test.tsx.snap is excluded by !**/*.snap
  • packages/react-templates/src/components/Dropdown/__tests__/__snapshots__/SimpleDropdown.test.tsx.snap is excluded by !**/*.snap
  • packages/react-templates/src/components/Select/__tests__/__snapshots__/CheckboxSelectSnapshots.test.tsx.snap is excluded by !**/*.snap
  • packages/react-templates/src/components/Select/__tests__/__snapshots__/MultiTypeaheadSelect.test.tsx.snap is excluded by !**/*.snap
  • packages/react-templates/src/components/Select/__tests__/__snapshots__/SimpleSelect.test.tsx.snap is excluded by !**/*.snap
  • packages/react-templates/src/components/Select/__tests__/__snapshots__/TypeaheadSelect.test.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (3)
  • packages/react-core/src/components/Form/examples/FormState.tsx
  • packages/react-core/src/components/MenuToggle/examples/MenuToggleAvatarText.tsx
  • packages/react-core/src/components/MenuToggle/examples/MenuTogglePlainCircle.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/react-core/src/components/Form/examples/FormState.tsx
  • packages/react-core/src/components/MenuToggle/examples/MenuToggleAvatarText.tsx

Walkthrough

Adds configurable aria-haspopup support to MenuToggle, defaults it to "menu", and updates MenuToggle examples plus Select-based examples to declare false or "listbox" popup semantics.

Changes

aria-haspopup support

Layer / File(s) Summary
MenuToggle prop and render logic
packages/react-core/src/components/MenuToggle/MenuToggle.tsx
Adds the optional prop, defaults it to "menu", and applies it across typeahead, split-button, and default buttons.
Non-popup MenuToggle examples
packages/react-core/src/components/MenuToggle/examples/*
MenuToggle examples explicitly pass aria-haspopup={false}; several are reformatted as multiline JSX.
Select example toggles
packages/react-core/src/components/Select/examples/*
Select toggle renderers now pass aria-haspopup="listbox".
Integrated Select examples
packages/react-core/src/components/Form/examples/FormState.tsx, packages/react-core/src/components/LoginPage/examples/LoginPageLanguageSelect.tsx, packages/react-core/src/components/Toolbar/examples/*, packages/react-core/src/components/Tooltip/examples/TooltipOptions.tsx
Additional Select-based toggles now declare aria-haspopup="listbox".

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: kmcfaul, thatblindgeye, dlabaj

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title concisely matches the main change: adding an aria-haspopup prop to MenuToggle.
Linked Issues check ✅ Passed The PR adds aria-haspopup with a menu default and updates Select-related usages to listbox as requested.
Out of Scope Changes check ✅ Passed The changes stay focused on MenuToggle accessibility and related example updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/react-core/src/components/MenuToggle/MenuToggle.tsx (1)

76-77: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Improve the JSDoc comment for the aria-haspopup prop.

The comment "Default value of aria-haspopup" doesn't describe what the prop does. A more descriptive comment would help consumers understand its purpose and valid values.

📝 Suggested comment improvement
-  /** Default value of aria-haspopup */
-  'aria-haspopup'?: 'menu' | 'listbox' | 'dialog' | boolean;
+  /** Indicates the type of popup controlled by this toggle. Defaults to 'menu'. */
+  'aria-haspopup'?: 'menu' | 'listbox' | 'dialog' | boolean;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/react-core/src/components/MenuToggle/MenuToggle.tsx` around lines 76
- 77, The JSDoc for the aria-haspopup prop in MenuToggleProps is too generic and
should describe the prop’s purpose and accepted values instead of only stating a
default. Update the comment near the aria-haspopup declaration in MenuToggle.tsx
to explain that it indicates what kind of popup the toggle controls, and mention
the allowed values used by the MenuToggle component. Keep the wording concise
and aligned with the prop’s accessibility intent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/react-core/src/components/MenuToggle/MenuToggle.tsx`:
- Around line 76-77: The JSDoc for the aria-haspopup prop in MenuToggleProps is
too generic and should describe the prop’s purpose and accepted values instead
of only stating a default. Update the comment near the aria-haspopup declaration
in MenuToggle.tsx to explain that it indicates what kind of popup the toggle
controls, and mention the allowed values used by the MenuToggle component. Keep
the wording concise and aligned with the prop’s accessibility intent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1ee5ada4-c051-46db-8e2e-10e12fdfc4ed

📥 Commits

Reviewing files that changed from the base of the PR and between f8bcd7c and 122aebb.

⛔ Files ignored due to path filters (1)
  • packages/react-core/src/components/MenuToggle/__tests__/__snapshots__/MenuToggle.test.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (22)
  • packages/react-core/src/components/Form/examples/FormState.tsx
  • packages/react-core/src/components/LoginPage/examples/LoginPageLanguageSelect.tsx
  • packages/react-core/src/components/MenuToggle/MenuToggle.tsx
  • packages/react-core/src/components/Select/examples/SelectBasic.tsx
  • packages/react-core/src/components/Select/examples/SelectCheckbox.tsx
  • packages/react-core/src/components/Select/examples/SelectFooter.tsx
  • packages/react-core/src/components/Select/examples/SelectGrouped.tsx
  • packages/react-core/src/components/Select/examples/SelectMultiTypeahead.tsx
  • packages/react-core/src/components/Select/examples/SelectMultiTypeaheadCheckbox.tsx
  • packages/react-core/src/components/Select/examples/SelectMultiTypeaheadCreatable.tsx
  • packages/react-core/src/components/Select/examples/SelectOptionVariations.tsx
  • packages/react-core/src/components/Select/examples/SelectTypeahead.tsx
  • packages/react-core/src/components/Select/examples/SelectTypeaheadCreatable.tsx
  • packages/react-core/src/components/Select/examples/SelectValidated.tsx
  • packages/react-core/src/components/Select/examples/SelectViewMore.tsx
  • packages/react-core/src/components/Toolbar/examples/ToolbarComponentManagedToggleGroups.tsx
  • packages/react-core/src/components/Toolbar/examples/ToolbarConsumerManagedToggleGroups.tsx
  • packages/react-core/src/components/Toolbar/examples/ToolbarCustomLabelGroupContent.tsx
  • packages/react-core/src/components/Toolbar/examples/ToolbarGroups.tsx
  • packages/react-core/src/components/Toolbar/examples/ToolbarStacked.tsx
  • packages/react-core/src/components/Toolbar/examples/ToolbarWithFilters.tsx
  • packages/react-core/src/components/Tooltip/examples/TooltipOptions.tsx

@thatblindgeye

Copy link
Copy Markdown
Contributor

/deploy-preview

@patternfly-build

patternfly-build commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

@thatblindgeye thatblindgeye left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition to the file comments below:

  • There's a bunch of lint errors being flagged, pretty much just putting the new aria-haspopup additions on its own line (instead of <MenuToggle aria-haspopup...
  • Some snapshot tests are failing, so those just need to be updated
  • For the various MenuToggle examples, can we just pass aria-haspopup={false} to those? Those examples are more static so they don't actually open anything, so we should avoid them announcing that they popup something

/** Adds styling which affects the size of the menu toggle */
size?: 'default' | 'sm';
/** Default value of aria-haspopup */
'aria-haspopup'?: 'menu' | 'listbox' | 'dialog' | boolean;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can omit the "dialog" option here for now. I can't think off the top of my head when the MenuToggle would trigger a dialog to open. We can always other the other allowed values down the line.

badge?: BadgeProps | React.ReactNode;
/** Adds styling which affects the size of the menu toggle */
size?: 'default' | 'sm';
/** Default value of aria-haspopup */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** Default value of aria-haspopup */
/** Indicates what type of popup will be triggered by the menu toggle. A value of true is the same as a value of "menu". */

- Remove 'dialog' from aria-haspopup type definition
- Update JSDoc comment as suggested
- Fix lint errors by placing aria-haspopup on its own line
- Set aria-haspopup={false} on static MenuToggle examples
- Update snapshots
@Axel-DaMage

Copy link
Copy Markdown
Contributor Author

All the feedback addressed, thanks for the review @thatblindgeye.

  • Lint errors: aria-haspopup is now properly placed on its own line across all files.
  • Snapshots: DatePicker snapshot now reflects the new default attribute.
  • Static MenuToggle examples: Added aria-haspopup={false} so they don't falsely announce a popup.
  • Removed "dialog" from the allowed type values.
  • JSDoc: Updated to your suggested wording.
  • Updated the missing snapshots in react-templates and react-table (deprecated) packages so the CI can pass.

@thatblindgeye thatblindgeye left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just needs a rebase to resolve conflicts otherwise lgtm, thank you!

@thatblindgeye thatblindgeye left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually quick update: the MenuTogglePlainCircle example file needs aria-haspopup of false on a couple other MenuToggles

@Axel-DaMage

Copy link
Copy Markdown
Contributor Author

The latest feedback has been addressed @thatblindgeye:

  • Added aria-haspopup={false} to the remaining MenuToggles in MenuTogglePlainCircle.
  • Resolved the merge conflict in MenuToggleAvatarText.tsx, keeping both the Avatar size="sm" and aria-haspopup={false} changes.

All checks are now passing, Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MenuToggle - add aria-haspopup prop

4 participants