diff --git a/blocksuite/affine/components/src/toolbar/menu-button.ts b/blocksuite/affine/components/src/toolbar/menu-button.ts index 2f83d53652..314ea22504 100644 --- a/blocksuite/affine/components/src/toolbar/menu-button.ts +++ b/blocksuite/affine/components/src/toolbar/menu-button.ts @@ -46,6 +46,12 @@ export class EditorMenuButton extends WithDisposable(LitElement) { composed: true, }) ); + + if (opened) { + this.dataset.open = 'true'; + } else { + delete this.dataset.open; + } }, mainAxis: 0, offsetHeight: 6 * 4, diff --git a/blocksuite/affine/widgets/toolbar/src/toolbar.ts b/blocksuite/affine/widgets/toolbar/src/toolbar.ts index 145b25044b..2052b641ad 100644 --- a/blocksuite/affine/widgets/toolbar/src/toolbar.ts +++ b/blocksuite/affine/widgets/toolbar/src/toolbar.ts @@ -3,6 +3,7 @@ import { EdgelessLegacySlotIdentifier } from '@blocksuite/affine-block-surface'; import { TableSelection } from '@blocksuite/affine-block-table'; import { darkToolbarStyles, + type EditorMenuButton, EditorToolbar, lightToolbarStyles, } from '@blocksuite/affine-components/toolbar'; @@ -618,7 +619,7 @@ export class AffineToolbarWidget extends WidgetComponent { }) ); - // Update layout when placement changing to `inner` + // Updates layout when placement changing to `inner` disposables.add( effect(() => { toolbar.dataset.placement = placement$.value; @@ -632,6 +633,10 @@ export class AffineToolbarWidget extends WidgetComponent { // Hides toolbar if (Flag.None === value || flags.check(Flag.Hiding, value)) { if (toolbar.dataset.open) delete toolbar.dataset.open; + // Closes dropdown menus + toolbar + .querySelector('editor-menu-button[data-open]') + ?.hide(); return; } diff --git a/blocksuite/affine/widgets/toolbar/src/utils.ts b/blocksuite/affine/widgets/toolbar/src/utils.ts index cfff88b6c7..3d9f2fb3f6 100644 --- a/blocksuite/affine/widgets/toolbar/src/utils.ts +++ b/blocksuite/affine/widgets/toolbar/src/utils.ts @@ -1,4 +1,5 @@ import { + type EditorMenuButton, type EditorToolbar, renderToolbarSeparator, } from '@blocksuite/affine-components/toolbar'; @@ -129,6 +130,10 @@ export function autoUpdatePosition( if (toolbar.dataset.open) { if (middlewareData.hide.referenceHidden) { delete toolbar.dataset.open; + // Closes dropdown menus + toolbar + .querySelector('editor-menu-button[data-open]') + ?.hide(); } } else { toolbar.dataset.open = 'true'; diff --git a/tests/affine-local/e2e/blocksuite/toolbar.spec.ts b/tests/affine-local/e2e/blocksuite/toolbar.spec.ts index 7d3a4642e2..823cdacd2d 100644 --- a/tests/affine-local/e2e/blocksuite/toolbar.spec.ts +++ b/tests/affine-local/e2e/blocksuite/toolbar.spec.ts @@ -319,3 +319,37 @@ test('should focus on input of popover on toolbar', async ({ page }) => { const cornersValue = await cornersInput.inputValue(); expect(cornersValue).toBe('36'); }); + +test('Dropdown menus should be closed automatically when toolbar is displayed', async ({ + page, +}) => { + await page.keyboard.press('Enter'); + await page.keyboard.type('/frame'); + await page.keyboard.press('Enter'); + + const toolbar = locateToolbar(page); + + const surfaceRef = page.locator('affine-surface-ref'); + await surfaceRef.hover(); + + await expect(toolbar).toBeVisible(); + + const moreMenuContainer = toolbar.getByLabel('More menu'); + const moreMenuButton = moreMenuContainer.getByLabel('More'); + const moreMenu = moreMenuContainer.getByRole('menu'); + + await expect(moreMenu).toBeHidden(); + + await moreMenuButton.click(); + + await expect(moreMenu).toBeVisible(); + + await page.mouse.move(0, 0); + + await expect(toolbar).toBeHidden(); + + await surfaceRef.hover(); + + await expect(toolbar).toBeVisible(); + await expect(moreMenu).toBeHidden(); +});