diff --git a/change/@fluentui-react-menu-cd75874c-429a-4082-8ba3-de74b0cd50b8.json b/change/@fluentui-react-menu-cd75874c-429a-4082-8ba3-de74b0cd50b8.json new file mode 100644 index 0000000000000..9caf8fadba213 --- /dev/null +++ b/change/@fluentui-react-menu-cd75874c-429a-4082-8ba3-de74b0cd50b8.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Bug fix for #18318 which ensures that a specified id attribute placed on the first trigger child is used for the menu aria-labelledby when provided", + "packageName": "@fluentui/react-menu", + "email": "ijackson145@gmail.com", + "dependentChangeType": "patch" +} diff --git a/packages/react-components/react-menu/src/components/Menu/Menu.test.tsx b/packages/react-components/react-menu/src/components/Menu/Menu.test.tsx index 58d3fe512e16d..07284b2144743 100644 --- a/packages/react-components/react-menu/src/components/Menu/Menu.test.tsx +++ b/packages/react-components/react-menu/src/components/Menu/Menu.test.tsx @@ -397,4 +397,23 @@ describe('Menu', () => { expect(container.querySelector('#second')?.getAttribute('aria-checked')).toBe('true'); expect(container.querySelector('#third')?.getAttribute('aria-checked')).toBe('false'); }); + + it('should render correct aria-labelledby attribute from corresponding trigger id', () => { + const customId = 'myTrigger'; + const { getByRole } = render( + + + + + + + Item + + + , + ); + + // Assert + expect(getByRole('menu')).toHaveAttribute('aria-labelledby', customId); + }); }); diff --git a/packages/react-components/react-menu/src/components/Menu/useMenu.tsx b/packages/react-components/react-menu/src/components/Menu/useMenu.tsx index 507b8f072ccad..7ecc02b78f646 100644 --- a/packages/react-components/react-menu/src/components/Menu/useMenu.tsx +++ b/packages/react-components/react-menu/src/components/Menu/useMenu.tsx @@ -54,7 +54,7 @@ export const useMenu_unstable = (props: MenuProps): MenuState => { defaultCheckedValues, mountNode = null, } = props; - const triggerId = useId('menu'); + let triggerId = useId('menu'); const [contextTarget, setContextTarget] = usePositioningMouseTarget(); const positioningState = { @@ -87,6 +87,9 @@ export const useMenu_unstable = (props: MenuProps): MenuState => { } else if (children.length === 1) { menuPopover = children[0]; } + if (menuTrigger?.props?.children?.props?.id) { + triggerId = menuTrigger.props.children.props.id; + } const { targetRef: triggerRef, containerRef: menuPopoverRef } = usePositioning(positioningState);