diff --git a/core/src/components/menu-button/test/async/index.html b/core/src/components/menu-button/test/async/index.html new file mode 100644 index 0000000000..105b9a3b87 --- /dev/null +++ b/core/src/components/menu-button/test/async/index.html @@ -0,0 +1,64 @@ + + + + + Menu - Async + + + + + + + + + + + + + +
+ + + Menu - Async + + + + + Main Content + + +
+
+ + + + diff --git a/core/src/components/menu-button/test/async/menu-button.e2e.ts b/core/src/components/menu-button/test/async/menu-button.e2e.ts new file mode 100644 index 0000000000..9d06238b19 --- /dev/null +++ b/core/src/components/menu-button/test/async/menu-button.e2e.ts @@ -0,0 +1,25 @@ +import { expect } from '@playwright/test'; +import { configs, test } from '@utils/test/playwright'; + +/** + * This behavior does not vary across modes/directions + */ +configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => { + test.describe(title('menu button: async'), () => { + test('menu button should be visible if menu is moved', async ({ page }) => { + await page.goto(`/src/components/menu-button/test/async`, config); + + const menu = page.locator('ion-menu'); + const menuButton = page.locator('ion-menu-button'); + const triggerButton = page.locator('#trigger'); + + await expect(menu).not.toBeAttached(); + await expect(menuButton).toBeHidden(); + + await triggerButton.click(); + + await expect(menu).toBeAttached(); + await expect(menuButton).toBeVisible(); + }); + }); +}); diff --git a/core/src/components/menu/menu.tsx b/core/src/components/menu/menu.tsx index c010e72d2d..5072bb74cd 100644 --- a/core/src/components/menu/menu.tsx +++ b/core/src/components/menu/menu.tsx @@ -38,6 +38,7 @@ export class Menu implements ComponentInterface, MenuI { private lastOnEnd = 0; private gesture?: Gesture; private blocker = GESTURE_CONTROLLER.createBlocker({ disableScroll: true }); + private didLoad = false; isAnimating = false; width!: number; @@ -216,6 +217,7 @@ export class Menu implements ComponentInterface, MenuI { // register this menu with the app's menu controller menuController._register(this); + this.menuChanged(); this.gesture = (await import('../../utils/gesture')).createGesture({ el: document, @@ -237,10 +239,22 @@ export class Menu implements ComponentInterface, MenuI { } async componentDidLoad() { - this.ionMenuChange.emit({ disabled: this.disabled, open: this._isOpen }); + this.didLoad = true; + this.menuChanged(); this.updateState(); } + private menuChanged() { + /** + * Inform dependent components such as ion-menu-button + * that the menu is ready. Note that we only want to do this + * once the menu has been rendered which is why we check for didLoad. + */ + if (this.didLoad) { + this.ionMenuChange.emit({ disabled: this.disabled, open: this._isOpen }); + } + } + async disconnectedCallback() { /** * The menu should be closed when it is