diff --git a/change/@fluentui-web-components-a2f01802-9f4b-483a-b2f1-b32511fd368c.json b/change/@fluentui-web-components-a2f01802-9f4b-483a-b2f1-b32511fd368c.json new file mode 100644 index 00000000000000..4d522e7fb7dbca --- /dev/null +++ b/change/@fluentui-web-components-a2f01802-9f4b-483a-b2f1-b32511fd368c.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "remove tooltip id from target’s aria-describedby attribute when the tooltip is removed from DOM", + "packageName": "@fluentui/web-components", + "email": "machi@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/src/tooltip/tooltip.spec.ts b/packages/web-components/src/tooltip/tooltip.spec.ts index 48161f4e710344..8f6ca63bb49075 100644 --- a/packages/web-components/src/tooltip/tooltip.spec.ts +++ b/packages/web-components/src/tooltip/tooltip.spec.ts @@ -71,6 +71,29 @@ test.describe('Tooltip', () => { await expect(button).toHaveAttribute('aria-describedby', id); }); + test('should remove the tooltip id from `aria-describedby` attribute when tooltip is removed', async ({ + fastPage, + }) => { + const { element, page } = fastPage; + const button = page.locator('button'); + + await fastPage.setTemplate(/* html */ ` +
+ + <${tagName} anchor="target">This is a tooltip + <${tagName} anchor="target">This is another tooltip +
+ `); + + const id2 = await element.nth(1).evaluate((node: Tooltip) => node.id); + + await element.nth(0).evaluate(node => { + node.remove(); + }); + + await expect(button).toHaveAttribute('aria-describedby', id2); + }); + test('should not be visible by default', async ({ fastPage }) => { const { element } = fastPage; diff --git a/packages/web-components/src/tooltip/tooltip.ts b/packages/web-components/src/tooltip/tooltip.ts index 9ff69650d7f0d9..6821483d3d1957 100644 --- a/packages/web-components/src/tooltip/tooltip.ts +++ b/packages/web-components/src/tooltip/tooltip.ts @@ -115,11 +115,25 @@ export class Tooltip extends FASTElement { } public disconnectedCallback(): void { - super.disconnectedCallback(); this.anchorElement?.removeEventListener('focus', this.focusAnchorHandler); this.anchorElement?.removeEventListener('blur', this.blurAnchorHandler); this.anchorElement?.removeEventListener('mouseenter', this.mouseenterAnchorHandler); this.anchorElement?.removeEventListener('mouseleave', this.mouseleaveAnchorHandler); + + if (this.anchorElement) { + const describedBy = this.anchorElement.getAttribute('aria-describedby') ?? ''; + const ids = describedBy + .trim() + .split(/\s+/) + .filter(id => id !== this.id); + if (ids.length) { + this.anchorElement.setAttribute('aria-describedby', ids.join(' ')); + } else { + this.anchorElement.removeAttribute('aria-describedby'); + } + } + + super.disconnectedCallback(); } /**