From bc620a1b40700bb9f0d770eac37f288513002970 Mon Sep 17 00:00:00 2001 From: Jeff Smith <37851214+eljefe223@users.noreply.github.com> Date: Mon, 14 Oct 2024 12:33:54 -0700 Subject: [PATCH] [fix][menu-item]: Emit current state when checked change event fires (#33029) Co-authored-by: John Kreitlow <863023+radium-v@users.noreply.github.com> --- ...-32b505fd-a856-47b9-9639-f9ce57af0ce4.json | 7 ++ .../web-components/src/menu-item/menu-item.ts | 2 +- .../src/menu-list/menu-list.spec.ts | 67 +++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 change/@fluentui-web-components-32b505fd-a856-47b9-9639-f9ce57af0ce4.json diff --git a/change/@fluentui-web-components-32b505fd-a856-47b9-9639-f9ce57af0ce4.json b/change/@fluentui-web-components-32b505fd-a856-47b9-9639-f9ce57af0ce4.json new file mode 100644 index 0000000000000..d1595ee34306d --- /dev/null +++ b/change/@fluentui-web-components-32b505fd-a856-47b9-9639-f9ce57af0ce4.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Fix: menu-item emit current state when checked change event fires", + "packageName": "@fluentui/web-components", + "email": "jes@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/src/menu-item/menu-item.ts b/packages/web-components/src/menu-item/menu-item.ts index 9e4ffb34bfb09..de751a9d6fffe 100644 --- a/packages/web-components/src/menu-item/menu-item.ts +++ b/packages/web-components/src/menu-item/menu-item.ts @@ -111,7 +111,7 @@ export class MenuItem extends FASTElement { toggleState(this.elementInternals, 'checked', checkableMenuItem ? next : false); if (this.$fastController.isConnected) { - this.$emit('change'); + this.$emit('change', next, { bubbles: true }); } } diff --git a/packages/web-components/src/menu-list/menu-list.spec.ts b/packages/web-components/src/menu-list/menu-list.spec.ts index d4dcf9cd0447e..c099c3138bce6 100644 --- a/packages/web-components/src/menu-list/menu-list.spec.ts +++ b/packages/web-components/src/menu-list/menu-list.spec.ts @@ -1,6 +1,8 @@ +import { once } from 'events'; import { test } from '@playwright/test'; import { expect, fixtureURL } from '../helpers.tests.js'; import { MenuItemRole } from '../menu-item/menu-item.options.js'; +import { MenuItem } from '../menu-item/menu-item.js'; test.describe('Menu', () => { test.beforeEach(async ({ page }) => { @@ -521,4 +523,69 @@ test.describe('Menu', () => { await expect(item).toHaveAttribute('data-indent', '2'); } }); + + test.describe('`change` event', () => { + test('should emit `change` event when `checked` property changed', async ({ page }) => { + const element = page.locator('fluent-menu-list'); + const menuItems = element.locator('fluent-menu-item'); + + await page.setContent(/* html */ ` + + Menu Item 1 + Menu item 2 + Menu item 3 + Menu item 4 + + `); + + const [wasChanged] = await Promise.all([ + menuItems + .nth(0) + .evaluate( + node => new Promise(resolve => node.addEventListener('change', () => resolve(true), { once: true })), + ), + menuItems.nth(0).evaluate((node: MenuItem) => { + node.checked = true; + }), + ]); + + expect(wasChanged).toEqual(true); + }); + + test('should emit change event when menu-item checked and unchecked', async ({ page }) => { + const element = page.locator('fluent-menu-list'); + const menuItems = element.locator('fluent-menu-item'); + + await page.setContent(/* html */ ` + + Menu Item 1 + Menu item 2 + Menu item 3 + Menu item 4 + + `); + + let wasChanged = menuItems.nth(0).evaluate((node: MenuItem) => { + return new Promise(resolve => { + node.addEventListener('change', evt => { + resolve((evt as any).detail); + }); + }); + }); + + await menuItems.nth(0).click(); + await expect(wasChanged).resolves.toBeTruthy(); + + wasChanged = menuItems.nth(0).evaluate((node: MenuItem) => { + return new Promise(resolve => { + node.addEventListener('change', evt => { + resolve((evt as any).detail); + }); + }); + }); + + await menuItems.nth(1).click(); + await expect(wasChanged).resolves.toBeFalsy(); + }); + }); });