diff --git a/change/@fluentui-react-infobutton-1b09e7d8-69ff-4983-9b7c-420f583f8d73.json b/change/@fluentui-react-infobutton-1b09e7d8-69ff-4983-9b7c-420f583f8d73.json new file mode 100644 index 0000000000000..cc13b45fad2a4 --- /dev/null +++ b/change/@fluentui-react-infobutton-1b09e7d8-69ff-4983-9b7c-420f583f8d73.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "fix(react-infobutton): Make InfoLabel only add aria-owns when the popover is open.", + "packageName": "@fluentui/react-infobutton", + "email": "esteban.230@hotmail.com", + "dependentChangeType": "patch" +} diff --git a/packages/react-components/react-infobutton/src/components/InfoLabel/InfoLabel.test.tsx b/packages/react-components/react-infobutton/src/components/InfoLabel/InfoLabel.test.tsx index c47219af13f98..15b0bd31454d9 100644 --- a/packages/react-components/react-infobutton/src/components/InfoLabel/InfoLabel.test.tsx +++ b/packages/react-components/react-infobutton/src/components/InfoLabel/InfoLabel.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -import { render } from '@testing-library/react'; +import { fireEvent, render } from '@testing-library/react'; import { isConformant } from '../../testing/isConformant'; import { InfoLabel } from './InfoLabel'; @@ -44,13 +44,21 @@ describe('InfoLabel', () => { expect(infoButton.getAttribute('aria-labelledby')).toBe(`${label.id} ${infoButton.id}`); }); - it("applies InfoButton's info slot id to aria-owns on the InfoLabel's wrapper", () => { + it("applies InfoButton's info slot id to aria-owns on the InfoLabel's wrapper when open", () => { const { container } = render(); + expect(container.getElementsByClassName('info-label-wrapper')[0].getAttribute('aria-owns')).toBeNull(); + + fireEvent.click(container.getElementsByTagName('button')[0]); + expect(container.getElementsByClassName('info-label-wrapper')[0].getAttribute('aria-owns')).toBe('test-id'); }); it("applies InfoButton's correct id to aria-owns on the InfoLabel's wrapper when id is provided to the infoButton slot", () => { const { container } = render(); + expect(container.getElementsByClassName('info-label-wrapper')[0].getAttribute('aria-owns')).toBeNull(); + + fireEvent.click(container.getElementsByTagName('button')[0]); + expect(container.getElementsByClassName('info-label-wrapper')[0].getAttribute('aria-owns')).toBe('test-id'); }); }); diff --git a/packages/react-components/react-infobutton/src/components/InfoLabel/useInfoLabel.ts b/packages/react-components/react-infobutton/src/components/InfoLabel/useInfoLabel.ts index 545442eb6a0e8..7d6357f19285f 100644 --- a/packages/react-components/react-infobutton/src/components/InfoLabel/useInfoLabel.ts +++ b/packages/react-components/react-infobutton/src/components/InfoLabel/useInfoLabel.ts @@ -1,7 +1,7 @@ import * as React from 'react'; import { Label } from '@fluentui/react-label'; -import { resolveShorthand, useId } from '@fluentui/react-utilities'; +import { mergeCallbacks, resolveShorthand, useEventCallback, useId } from '@fluentui/react-utilities'; import { InfoButton } from '../InfoButton/InfoButton'; import type { InfoLabelProps, InfoLabelState } from './InfoLabel.types'; @@ -26,6 +26,7 @@ export const useInfoLabel_unstable = (props: InfoLabelProps, ref: React.Ref { + setOpen(data.open); + }), + ); + if (infoButton) { + infoButton.popover = infoButtonPopover; infoButton.info = resolveShorthand(infoButton?.info, { defaultProps: { id: baseId + '__info', @@ -62,7 +71,10 @@ export const useInfoLabel_unstable = (props: InfoLabelProps, ref: React.Ref) => { const labelId = useId('label'); const infobuttonId = useId('infobutton'); const infobuttonInfoId = infobuttonId + '__info'; - const [open, setOpen] = React.useState(false); - const info = ( - <> - This is example information for an InfoButton. Learn more - - ); - - const onOpenChange: PopoverProps['onOpenChange'] = (e, data) => setOpen(data.open); + const onOpenChange: PopoverProps['onOpenChange'] = (e, data) => { + setOpen(data.open); + }; return (
@@ -35,7 +30,7 @@ export const Default = (props: Partial) => { className={styles.infoButton} info={{ id: infobuttonInfoId, - children: info, + children: 'This is example information for an InfoButton.', }} popover={{ onOpenChange, diff --git a/packages/react-components/react-infobutton/stories/InfoButton/InfoButtonSize.stories.tsx b/packages/react-components/react-infobutton/stories/InfoButton/InfoButtonSize.stories.tsx index 7404b280b2dc8..0805e5dac432d 100644 --- a/packages/react-components/react-infobutton/stories/InfoButton/InfoButtonSize.stories.tsx +++ b/packages/react-components/react-infobutton/stories/InfoButton/InfoButtonSize.stories.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { InfoButton } from '@fluentui/react-infobutton'; -import { Label, Link, makeStyles, shorthands, useId } from '@fluentui/react-components'; +import { Label, makeStyles, shorthands, useId } from '@fluentui/react-components'; import type { InfoButtonProps } from '@fluentui/react-infobutton'; import type { PopoverProps } from '@fluentui/react-components'; @@ -19,28 +19,19 @@ const useStyles = makeStyles({ const InfoButtonSize: React.FC<{ size: InfoButtonProps['size'] }> = ({ size }) => { const styles = useStyles(); - const labelId = useId('label'); - const infobuttonId = useId('infobutton'); - const infobuttonInfoId = infobuttonId + '__info'; - + const infobuttonInfoId = useId('infobuton__info'); const [open, setOpen] = React.useState(false); + const info = 'This is example information for an InfoButton.'; - const info = ( - <> - This is example information for an InfoButton. Learn more - - ); - - const onOpenChange: PopoverProps['onOpenChange'] = (e, data) => setOpen(data.open); + const onOpenChange: PopoverProps['onOpenChange'] = (e, data) => { + setOpen(data.open); + }; return (
- +