Skip to content

Add ActionMenu.IconButton and ActionMenu.Anchor child validation#7640

Draft
Copilot wants to merge 6 commits intomainfrom
copilot/fix-actionmenu-anchor-validation
Draft

Add ActionMenu.IconButton and ActionMenu.Anchor child validation#7640
Copilot wants to merge 6 commits intomainfrom
copilot/fix-actionmenu-anchor-validation

Conversation

Copy link
Contributor

Copilot AI commented Mar 9, 2026

ActionMenu.Anchor accepts arbitrary children, making it easy to wrap non-interactive elements (e.g., <div>) and produce inaccessible markup. The most common use case for ActionMenu.Anchor is wrapping IconButton, which should have a blessed shortcut.

This PR adds two things:

  1. ActionMenu.IconButton — syntactic sugar (like ActionMenu.Button) that correctly wires an IconButton as the menu anchor
  2. ActionMenu.Anchor child validation — dev-only warning when the anchor child is not an interactive element, following the same pattern used in Tooltip
// Before: manual wiring required
<ActionMenu>
  <ActionMenu.Anchor>
    <IconButton icon={KebabHorizontalIcon} aria-label="More actions" />
  </ActionMenu.Anchor>
  <ActionMenu.Overlay>...</ActionMenu.Overlay>
</ActionMenu>

// After: blessed shortcut
<ActionMenu>
  <ActionMenu.IconButton icon={KebabHorizontalIcon} aria-label="More actions" />
  <ActionMenu.Overlay>...</ActionMenu.Overlay>
</ActionMenu>

The validation warns on non-interactive anchors but skips submenu contexts where ActionList.Item is the expected anchor.

Changelog

New

  • ActionMenu.IconButton — shortcut for using IconButton as menu trigger, equivalent to wrapping it in ActionMenu.Anchor
  • ActionMenuIconButtonProps type export
  • Dev-only console.warn when ActionMenu.Anchor receives a non-interactive child element

Changed

  • ActionMenu.Anchor now uses useMergedRefs to combine an internal ref (for child validation) with the forwarded ref

Removed

None

Rollout strategy

  • Patch release
  • Minor release
  • Major release; if selected, include a written rollout or migration plan
  • None; if selected, include a brief description as to why

Testing & Reviewing

  • New tests cover ActionMenu.IconButton (open/close, event handlers, id forwarding)
  • New tests verify the warning fires for non-interactive anchors (<div>) and does not fire for Button or IconButton
  • Submenu tests confirm no false-positive warnings for ActionList.Item anchors
  • Type tests validate ActionMenu.IconButton prop types

Merge checklist


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@changeset-bot
Copy link

changeset-bot bot commented Mar 9, 2026

⚠️ No Changeset found

Latest commit: d6d9c33

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copilot AI linked an issue Mar 9, 2026 that may be closed by this pull request
Copilot AI and others added 2 commits March 9, 2026 11:09
- Add ActionMenu.IconButton as a shortcut companion to ActionMenu.Button
  that wraps IconButton and wires it correctly as an ActionMenu anchor
- Add validation in ActionMenu.Anchor to warn when the child is a
  non-interactive element (skips validation for submenu anchors)
- Add tests for both features
- Add type tests for ActionMenu.IconButton
- Update exports in index.ts

Co-authored-by: siddharthkp <1863771+siddharthkp@users.noreply.github.com>
Co-authored-by: siddharthkp <1863771+siddharthkp@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix ActionMenu.Anchor to only accept button elements Add ActionMenu.IconButton and ActionMenu.Anchor child validation Mar 9, 2026
@siddharthkp siddharthkp requested a review from Copilot March 9, 2026 11:45
@github-actions github-actions bot added the integration-tests: recommended This change needs to be tested for breaking changes. See https://arc.net/l/quote/tdmpakpm label Mar 9, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 9, 2026

⚠️ Action required

👋 Hi, this pull request contains changes to the source code that github/github-ui depends on. If you are GitHub staff, test these changes with github/github-ui using the integration workflow. Or, apply the integration-tests: skipped manually label to skip these checks.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a first-class ActionMenu.IconButton trigger and introduces dev-time validation for ActionMenu.Anchor children to reduce accidentally inaccessible menu triggers in @primer/react.

Changes:

  • Add ActionMenu.IconButton subcomponent (and ActionMenuIconButtonProps export) as a shortcut for using IconButton as the menu trigger.
  • Add dev-time ActionMenu.Anchor child validation that warns when the anchor element is not interactive (skipping submenu contexts).
  • Update docs/exports and add unit + type tests covering the new API and warning behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/react/src/index.ts Exports the new ActionMenuIconButtonProps type from the package entrypoint.
packages/react/src/tests/snapshots/exports.test.ts.snap Updates the public-exports snapshot to include ActionMenuIconButtonProps.
packages/react/src/ActionMenu/ActionMenu.types.test.tsx Adds type-level coverage for ActionMenu.IconButton props (valid/invalid).
packages/react/src/ActionMenu/ActionMenu.tsx Implements ActionMenu.IconButton and adds ActionMenu.Anchor interactive-child validation + merged refs.
packages/react/src/ActionMenu/ActionMenu.test.tsx Adds unit tests for ActionMenu.IconButton behavior and ActionMenu.Anchor warning behavior.
packages/react/src/ActionMenu/ActionMenu.docs.json Documents ActionMenu.IconButton as a passthrough to IconButton.

siddharthkp and others added 2 commits March 9, 2026 12:57
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@siddharthkp siddharthkp requested a review from Copilot March 9, 2026 11:57
@github-actions github-actions bot requested a deployment to storybook-preview-7640 March 9, 2026 12:01 Abandoned
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Comment on lines +284 to +290
ref: (node: HTMLElement | null) => {
internalRef.current = node
if (typeof anchorRef === 'function') {
anchorRef(node)
} else if (anchorRef) {
;(anchorRef as React.MutableRefObject<HTMLElement | null>).current = node
}
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

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

The anchor ref wiring is manually re-implementing ref merging and requires unsafe casts. Consider using the existing useMergedRefs helper (packages/react/src/internal/hooks/useMergedRefs.ts) to combine anchorRef and internalRef instead of an inline callback + casts; this also lets you drop the react-hooks/refs eslint disable.

Copilot uses AI. Check for mistakes.
Copy link
Member

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Replaced manual ref merging with useMergedRefs(internalRef, anchorRef) in d6d9c33. This removes the inline callback, the unsafe MutableRefObject cast, and the eslint-disable comment.

Co-authored-by: siddharthkp <1863771+siddharthkp@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

integration-tests: recommended This change needs to be tested for breaking changes. See https://arc.net/l/quote/tdmpakpm

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ActionMenu.Anchor should only accept button

3 participants