mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-22 13:32:11 +00:00
## Summary Stops the Shape submenu (and any other PrimeVue nested submenu) from being clipped behind the node context menu when the menu fits in the viewport. ## Changes - **What**: `constrainMenuHeight` in `NodeContextMenu.vue` now applies `max-height` + `overflow-y: auto` to the root `<ul>` only when `scrollHeight > availableHeight`. The common case keeps `overflow: visible`. - Added `browser_tests/tests/nodeContextMenuShapeSubmenu.spec.ts` regression spec. ## Review Focus Root cause: setting only `overflow-y: auto` on a `<ul>` coerces `overflow-x` to a non-visible value per CSS spec (`If one of overflow-x/overflow-y is visible and the other isn't, the visible value is computed as auto`). PrimeVue `ContextMenuSub` renders submenus in-tree as a nested `<ul>` with `position: absolute; left: 100%`, so the implicit horizontal clip hides them entirely. The pre-existing overflow scenario (#10824 / #10854) is unchanged — when the menu actually overflows, the clamp still applies and `nodeContextMenuOverflow.spec.ts` continues to verify scroll. Submenu clipping in that overflow case is a known limitation, not introduced by this PR. Fixes FE-570 ## screenshot ### AS IS <img width="788" height="505" alt="Screenshot 2026-05-07 at 12 43 26 PM" src="https://github.com/user-attachments/assets/36d34070-0c57-4385-a130-0394f22f282e" /> ### TO BE <img width="779" height="627" alt="Screenshot 2026-05-07 at 12 42 44 PM" src="https://github.com/user-attachments/assets/00956729-763b-4787-822f-209e8ea42331" /> ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-12035-fix-keep-node-context-menu-overflow-visible-when-content-fits-3586d73d365081ad9aaec82f220d401c) by [Unito](https://www.unito.io) --------- Co-authored-by: GitHub Action <action@github.com>
66 lines
2.3 KiB
TypeScript
66 lines
2.3 KiB
TypeScript
import { expect } from '@playwright/test'
|
|
|
|
import type { ComfyPage } from '@e2e/fixtures/ComfyPage'
|
|
import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage'
|
|
import { openMoreOptionsMenu } from '@e2e/fixtures/utils/selectionToolboxMoreOptions'
|
|
|
|
test.describe(
|
|
'Node context menu shape submenu (FE-570)',
|
|
{ tag: '@ui' },
|
|
() => {
|
|
test.beforeEach(async ({ comfyPage }) => {
|
|
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
|
|
await comfyPage.settings.setSetting('Comfy.Canvas.SelectionToolbox', true)
|
|
await comfyPage.workflow.loadWorkflow('nodes/single_ksampler')
|
|
})
|
|
|
|
async function expectShapePopoverVisible(comfyPage: ComfyPage) {
|
|
const popover = comfyPage.page
|
|
.locator('.p-popover')
|
|
.filter({ hasText: 'Default' })
|
|
await expect(popover).toBeVisible()
|
|
await expect(popover).toContainText('Box')
|
|
await expect(popover).toContainText('Card')
|
|
|
|
const popoverBox = await popover.boundingBox()
|
|
expect(popoverBox).not.toBeNull()
|
|
expect(popoverBox!.width).toBeGreaterThan(0)
|
|
expect(popoverBox!.height).toBeGreaterThan(0)
|
|
}
|
|
|
|
test('Shape popover opens when the menu fits in the viewport', async ({
|
|
comfyPage
|
|
}) => {
|
|
await comfyPage.page.setViewportSize({ width: 1280, height: 900 })
|
|
const menu = await openMoreOptionsMenu(comfyPage, 'KSampler')
|
|
const rootList = menu.locator(':scope > ul')
|
|
|
|
await expect
|
|
.poll(() => rootList.evaluate((el) => getComputedStyle(el).overflowY))
|
|
.toBe('visible')
|
|
|
|
await menu.getByRole('menuitem', { name: 'Shape' }).click()
|
|
await expectShapePopoverVisible(comfyPage)
|
|
})
|
|
|
|
test('Shape popover opens even when the menu must scroll', async ({
|
|
comfyPage
|
|
}) => {
|
|
await comfyPage.page.setViewportSize({ width: 1280, height: 520 })
|
|
const menu = await openMoreOptionsMenu(comfyPage, 'KSampler')
|
|
const rootList = menu.locator(':scope > ul')
|
|
|
|
await expect
|
|
.poll(() =>
|
|
rootList.evaluate((el) => el.scrollHeight > el.clientHeight)
|
|
)
|
|
.toBe(true)
|
|
|
|
const shapeItem = menu.getByRole('menuitem', { name: 'Shape' })
|
|
await shapeItem.scrollIntoViewIfNeeded()
|
|
await shapeItem.click()
|
|
await expectShapePopoverVisible(comfyPage)
|
|
})
|
|
}
|
|
)
|